javascript中的继承如何实现_原型链和类继承的区别是什么【教程】

13次阅读

javaScript类继承本质是原型链继承的语法糖,class通过隐式操作prototype和__proto__实现继承,new子类实例后能访问父类方法因原型链存在,手动实现需显式设置__proto__并修复constructor

javascript中的继承如何实现_原型链和类继承的区别是什么【教程】

javascript 中的继承不是“选哪种更好”,而是“类继承就是原型链继承的语法糖”——class 写法背后仍是操作 prototype__proto__,只是隐藏了手动赋值、修正 constructor 等细节。

为什么 new 一个子类实例后,能访问父类原型上的方法?

因为实例的 __proto__ 指向子类的 prototype,而子类 prototype.__proto__ 又指向父类 prototype,形成原型链。方法查找时沿这条链向上遍历。

手动实现时容易漏掉关键一步:

  • 子类 prototype 必须显式设置 __proto__(或用 Object.setPrototypeOf())指向父类 prototype
  • 否则子类实例无法访问父类原型方法,只继承构造函数内定义的属性
  • constructor 属性会被覆盖,需手动恢复:Child.prototype.constructor = Child

class extends 和手写 prototype 链的核心差异在哪?

差异不在机制,而在约束和默认行为:

立即学习Java免费学习笔记(深入)”;

  • classsuper() 强制调用父类构造函数,且必须在 this 使用前执行;手写方式不强制,但漏调会导致 this 未初始化
  • class 的子类 prototype 自动链接到父类 prototype,无需手动 setPrototypeOf
  • class 声明不被提升(ReferenceError),函数声明可提升
  • class 方法默认不可枚举;手写挂载到 prototype 上的方法默认可枚举(除非用 Object.defineProperty 显式设 enumerable: false

使用 Object.create(Parent.prototype) 时要注意什么?

这是最接近 class extends 行为的手写方式,但有几个易错点:

  • Object.create(Parent.prototype) 返回的是一个新对象,不能直接赋给 Child.prototype 后就完事——它会丢失 Child 自己定义的方法
  • 正确做法是:先 Child.prototype = Object.create(Parent.prototype),再往该对象上添加子类方法(或用 Object.assign 合并)
  • 必须重置 constructorChild.prototype.constructor = Child,否则 instance.constructor 指向 Parent
  • 如果父类构造函数有副作用(如绑定事件、发请求),Object.create 不会执行它——仅建立原型链,不调用构造逻辑
function Parent(name) {   this.name = name; } Parent.prototype.say = function() { return 'hi'; };  function Child(name, age) {   Parent.call(this, name); // 手动调用父构造   this.age = age; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; // 关键! Child.prototype.play = function() { return 'game'; };  const c = new Child('Alice', 12); console.log(c.say()); // 'hi' console.log(c.play()); // 'game' console.log(c.constructor === Child); // true

真正难的不是写出能跑的继承,而是理解每次 new 时发生了几层链接、哪些对象被修改、constructor 指针是否断裂——这些地方一错,instanceof 和序列化/调试都会出人意料。

text=ZqhQzanResources