JavaScript 的继承基于原型链机制,对象通过__proto__逐级向上查找属性和方法,而非复制;构造函数的prototype用于搭建链路,ES6 class仅为语法糖,本质仍是原型链委托查找。

JavaScript 中没有传统意义上的“类继承”,原型链就是它实现继承的底层机制——对象靠链接到另一个对象来复用属性和方法,而不是靠复制或声明式继承。
原型链的本质是一条查找路径
当你访问一个对象的属性,比如 obj.name,JS 引擎会:
- 先在 obj 自身查找 name;
- 没找到,就顺着 obj.__proto__ 去它的原型对象上找;
- 还没找到,就继续顺着那个原型的 __proto__ 往上找;
- 直到抵达 Object.prototype(它的 __proto__ 是 null),链就断了,返回 undefined。
这条从实例出发、逐级向上追溯的链条,就是原型链。它不负责“复制”,只负责“委托查找”。
构造函数与 prototype 是搭建链的“脚手架”
你写 function Person(name) { this.name = name; },其实做了两件事:
立即学习“Java免费学习笔记(深入)”;
- Person.prototype 自动生成一个空对象,所有 new Person() 创建的实例,其 __proto__ 都指向它;
- 你往 Person.prototype 上加方法(如 sayHello()),所有实例就能“共享使用”,不用每个都存一份。
这正是继承的起点:不是把父类代码搬进子类,而是让子类实例能顺着链,查到父类定义在原型上的能力。
真正的继承发生在原型链的拼接上
想让 Dog 继承 Animal,关键操作是:
- Dog.prototype = Object.create(Animal.prototype) —— 让 Dog 的原型对象的 __proto__ 指向 Animal.prototype;
- Dog.prototype.constructor = Dog —— 修正构造器引用,避免混淆;
- 再配合 Animal.call(this, ...) 在构造时继承实例属性。
这样,new Dog() 实例的原型链就变成:
dog → Dog.prototype → Animal.prototype → Object.prototype → null
于是 dog.sayHello() 虽然自身没有,但能一路查到 Animal.prototype.sayHello。
为什么说它是继承的基础?
因为所有 JS 对象的继承行为,都依赖这条动态查找链:
- 字面量对象 {} 继承自 Object.prototype,所以有 toString();
- 数组 [] 的原型链包含 Array.prototype,再往上还是 Object.prototype;
- ES6 的 class 只是语法糖,背后仍是这套原型链逻辑;
- 甚至函数本身也是对象,它的 __proto__ 指向 Function.prototype,而后者又连向 Object.prototype。
没有原型链,就没有属性/方法的跨对象共享,也就没有 JavaScript 意义上的“继承”。











