author: 专注前端开发,分享JavaScript干货
title: JavaScript高级②|原型与原型链,一张图彻底搞懂
update: 2026-04-28
tags: JavaScript,原型,原型链,proto,prototype,继承,前端进阶

作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:有JS基础,想理解对象模型和继承的开发者


前言:为什么需要原型?

JavaScript 没有传统类的概念,而是通过**原型(prototype)**实现对象之间的共享和继承。

不懂原型,JS的对象系统就是黑盒。


一、原型的两个核心规则

1.1 prototype 与 proto

// 规则1:函数有 prototype 属性
function Person(name) {
    this.name = name;
}
console.log(Person.prototype); // { constructor: Person, ... }

// 规则2:对象有 __proto__ 属性,指向它的原型
const p = new Person("张三");
console.log(p.__proto__ === Person.prototype); // true ✅

// 规则3:原型对象也有 __proto__,最终指向 null
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null (原型链终点)

1.2 一张图看懂原型链

实例对象 p
    ↓ __proto__
Person.prototype
    ↓ __proto__
Object.prototype
    ↓ __proto__
null (终点)

二、属性查找机制

访问对象属性时,JS会沿着原型链向上查找,直到 null。

function Person(name) {
    this.name = name;
}

// 在原型上添加方法(所有实例共享)
Person.prototype.sayHi = function() {
    console.log(`你好,我是${this.name}`);
};

const p1 = new Person("张三");
const p2 = new Person("李四");

p1.sayHi(); // "你好,我是张三" (从 p1.__proto__ 找到)
p2.sayHi(); // "你好,我是李四"

// 查找顺序演示
const obj = {};
console.log(obj.toString()); // 来自 Object.prototype
// obj 自身没有 toString
// → obj.__proto__ (Object.prototype) 找到了

三、constructor 属性

function Person() {}
const p = new Person();

console.log(Person.prototype.constructor === Person); // true
console.log(p.constructor === Person); // true
// p自身没有constructor,从 p.__proto__ (Person.prototype) 找到

// 重写 prototype 时要修正 constructor
Person.prototype = {
    // constructor: Person,  // ❌ 忘记写这个
    sayHi() { console.log("hi"); }
};
const p2 = new Person();
console.log(p2.constructor === Person); // false ❌(指向了Object)
console.log(p2.constructor === Object); // true

// ✅ 正确做法
Person.prototype = {
    constructor: Person,  // 手动修正
    sayHi() { console.log("hi"); }
};

四、原型链继承

4.1 传统继承方式

// 父类
function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function() {
    console.log(`${this.name}在吃东西`);
};

// 子类
function Dog(name, breed) {
    Animal.call(this, name); // 调用父类构造函数
    this.breed = breed;
}

// 设置原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修正constructor

// 子类方法
Dog.prototype.bark = function() {
    console.log(`${this.name}在汪汪叫`);
};

const dog = new Dog("旺财", "金毛");
dog.eat();  // "旺财在吃东西" (来自Animal.prototype)
dog.bark(); // "旺财在汪汪叫" (来自Dog.prototype)

4.2 ES6 class 语法(语法糖)

class Animal {
    constructor(name) {
        this.name = name;
    }
    eat() {
        console.log(`${this.name}在吃东西`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 调用父类构造函数
        this.breed = breed;
    }
    bark() {
        console.log(`${this.name}在汪汪叫`);
    }
}

const dog = new Dog("旺财", "金毛");
dog.eat();  // "旺财在吃东西"
dog.bark(); // "旺财在汪汪叫"
console.log(dog instanceof Dog);    // true
console.log(dog instanceof Animal); // true

五、instanceof 原理

// instanceof 检查原型链
function Person() {}
const p = new Person();

console.log(p instanceof Person);  // true
// 检查:p.__proto__ === Person.prototype → true

console.log(p instanceof Object);   // true
// 检查:p.__proto__.__proto__ === Object.prototype → true

// 手写 instanceof
function myInstanceof(obj, Constructor) {
    let proto = obj.__proto__;
    while (proto) {
        if (proto === Constructor.prototype) {
            return true;
        }
        proto = proto.__proto__;
    }
    return false;
}

六、原型污染与安全问题

// 原型污染:修改 Object.prototype 会影响所有对象
Object.prototype.isAdmin = true;
const obj = {};
console.log(obj.isAdmin); // true ❌ 所有对象都有了

// 安全做法:用 Object.create(null) 创建无原型对象
const safeObj = Object.create(null);
safeObj.name = "张三";
console.log(safeObj.toString); // undefined (没有原型链)

七、知识卡

概念 说明
prototype 函数的属性,用来共享方法
__proto__ 对象的属性,指向原型
原型链 对象查找属性的路径
constructor 指向构造函数
instanceof 检查是否在原型链上
Object.create() 创建指定原型的对象
class ES6 继承语法糖

八、课后作业

  1. 画出 const arr = [] 的原型链图
  2. 实现一个 new 的模拟函数 myNew(Constructor, ...args)
  3. 用原型链方式实现:父类 Vehicle,子类 Car 继承并添加 drive 方法

有问题欢迎评论区留言,大家一起讨论!


标签:JavaScript | 原型 | 原型链 | proto | prototype | 继承 | 前端进阶

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐