JavaScript继承基于原型链,非类机制:实例通过__proto__链接到构造函数的prototype,属性查找沿链向上直至null;class仅为语法糖,本质仍是原型委托。

JavaScript 的继承体系不是靠“类”定义出来的,而是靠对象之间的原型链接自然形成的。它的逻辑起点很简单:一个对象找不到某个属性时,就去它的原型上找;原型找不到,再去找原型的原型——这条逐级向上查找的路径,就是原型链,也是整个继承机制的底层依据。
原型链是怎么连起来的
每次用 new 调用构造函数时,JS 引擎会做三件事:
- 创建一个空对象
- 把这个对象的 [[Prototype]](通常可通过 __proto__ 访问)指向该构造函数的 prototype 对象
- 以这个新对象为 this 执行构造函数
所以,实例和构造函数的 prototype 之间,靠 __proto__ 这条隐式链接绑在一起。而函数的 prototype 本身又是一个普通对象,它的 __proto__ 指向 Object.prototype,最终链到 null 终止。
继承关系怎么建立
要让子类型能复用父类型的属性和方法,关键是让子类型的 prototype 指向父类型的实例(或等效结构):
立即学习“Java免费学习笔记(深入)”;
- Child.prototype = new Parent():最原始的方式,使 Child 的所有实例都能沿原型链访问 Parent.prototype 上的方法
- 但这样会导致父类引用类型属性被所有子实例共享,而且无法给父构造函数传参
- 更稳妥的做法是:Child.prototype = Object.create(Parent.prototype),再手动补回 constructor
这一步的本质,是让子类的原型对象“继承”父类的原型对象,而不是复制父类实例的数据。
属性查找怎么工作
当你写 obj.method(),JS 查找过程是线性的、单向的:
- 先查 obj 自身有没有 method
- 没有?就查 obj.__proto__(即构造函数的 prototype)
- 还没?继续查 obj.__proto__.__proto__(比如 Parent.prototype)
- 一直查到 Object.prototype,再往上就是 null,返回 undefined
这个过程不看构造函数名,只认 prototype 对象的内存地址是否匹配。所以 instanceof 判断的其实是:某个构造函数的 prototype 是否出现在该实例的原型链上。
为什么说它是“唯一”的继承模型
JavaScript 没有类继承,只有对象继承对象。所谓“子类”,只是原型链上位置更靠后的对象;所谓“父类”,只是它原型链上更靠前的一个对象。ES6 的 class 和 extends 全是语法糖,编译后仍是通过 Object.setPrototypeOf 或 __proto__ 设置原型关系来实现。
这种设计让继承非常灵活——你可以随时修改某个对象的原型,所有基于它的实例立刻生效;也可以让任意两个对象产生继承关系,不需要预设类结构。


















