JavaScript原型继承本质是通过原型链实现属性和方法的共享与查找:每个对象有[[Prototype]]指向其原型,原型也是对象,最终链至Object.prototype→null;函数有prototype属性,实例的__proto__指向其构造函数的prototype;ES6 class只是该机制的语法糖。

JavaScript 中的原型继承,本质是通过原型链实现对象间属性和方法的共享与查找。理解它不靠死记概念,而要抓住“每个对象都有一个内部链接指向它的原型,而原型本身也是对象,也有自己的原型,直到到达 null”这个链条逻辑。
每个函数都有 prototype 属性,每个实例都有 __proto__
函数(如 Person)创建时,JS 引擎自动为其添加一个 prototype 属性,它是一个普通对象,默认带有一个 constructor 指回该函数。当你用 new Person() 创建实例时,该实例的内部属性 __proto__ 会自动指向 Person.prototype。
例如:
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
return 'Hi, I am ' + this.name;
};
const p1 = new Person('Alice');
console.log(p1.__proto__ === Person.prototype); // true
console.log(p1.sayHi()); // 'Hi, I am Alice'
原型链是一条向上的查找路径
当访问一个对象的属性或方法时,JS 引擎先在对象自身查找;没找到,就顺着 __proto__ 去它的原型上找;还没找到,继续沿原型的 __proto__ 往上找,直到找到或抵达 Object.prototype(它的 __proto__ 是 null,链终止)。
立即学习“Java免费学习笔记(深入)”;
- p1.toString() 不在 p1 自身,也不在 Person.prototype,但能在 Object.prototype 找到
- Object.prototype.__proto__ === null,这是原型链的终点
- 可以用 Object.getPrototypeOf(p1) 安全获取原型,代替非标准的 __proto__
继承多个层级:用 Object.create 搭建链路
手动构建继承关系时,常用 Object.create(Parent.prototype) 让子类原型“继承”父类原型,再修正 constructor,并在子类构造函数中调用父类构造(Parent.call(this, ...))。
例如实现 Student 继承 Person:
function Student(name, grade) {
Person.call(this, name); // 复用父类初始化
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype); // 链接到 Person 原型
Student.prototype.constructor = Student; // 修复 constructor
Student.prototype.study = function() {
return this.name + ' is studying';
};
此时 new Student().__proto__ → Student.prototype → Person.prototype → Object.prototype → null,形成完整原型链。
ES6 class 只是语法糖,底层仍是原型链
class 和 extends 看似面向类,实际编译/运行时仍操作 prototype 和 __proto__。比如 class B extends A,等价于让 B.prototype.__proto__ 指向 A.prototype,并确保实例的 __proto__ 正确链接。
- 可直接用 Reflect.getPrototypeOf(obj) 查看某对象的直接原型
- 用 obj instanceof Constructor 判断原理就是检查原型链中是否包含 Constructor.prototype
- 修改原型上的方法,所有继承它的实例立即可见(动态性)


















