javascript中原型链是什么_它如何实现继承?

12次阅读

原型链是javaScript对象继承的核心机制,通过[[prototype]]内部槽隐式连接对象,属性查找沿链向上直至NULLObject.create()用于安全设置原型,Object.setPrototypeOf()应避免热路径使用。

javascript中原型链是什么_它如何实现继承?

原型链是 javascript 中实现对象继承的核心机制,不是语法糖,而是运行时对象间隐式连接的真实引用关系。

原型链的本质:每个对象都有一个 [[Prototype]] 内部槽

这个内部槽指向另一个对象(即它的原型),查找属性或方法时,若当前对象没有该属性,引擎会沿着 [[Prototype]] 链向上逐级查找,直到找到或到达 null(链的终点)。

  • Object.prototype[[Prototype]]null,它是绝大多数对象原型链的终点
  • obj.__proto__ 是访问 [[Prototype]] 的非标准但广泛支持的方式;标准方式是 Object.getPrototypeOf(obj)
  • function.prototype 是函数对象独有的属性,它被赋给用该函数创建的实例的 [[Prototype]](仅限 new 调用)

function 构造函数模拟“类继承”时的原型链设置

传统方式依赖手动修正 Child.prototype[[Prototype]],否则子类无法继承父类原型上的方法。

function Parent(name) {   this.name = name; } Parent.prototype.sayHello = function() {   return `Hello, ${this.name}`; };  function Child(name, age) {   Parent.call(this, name); // 继承实例属性   this.age = age; }  // 关键一步:让 Child.prototype 的 [[Prototype]] 指向 Parent.prototype Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; // 修复 constructor 指针  const c = new Child('Alice', 10); console.log(c.sayHello()); // "Hello, Alice" —— 成功从 Parent.prototype 查找
  • 漏掉 Object.create(Parent.prototype)Child.prototype 就只是个空对象,不继承任何方法
  • 漏掉 constructor = Childc.constructor 会错误地指向 Parent
  • es6 class 语法底层仍走这套逻辑,只是自动处理了上述两步

Object.setPrototypeOf()Object.create() 的实际差异

二者都能建立原型链接,但使用场景和性能影响不同:

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

  • Object.create(proto) 创建一个新对象,并将其 [[Prototype]] 设为 proto;适合初始化原型对象(如上例中重设 Child.prototype
  • Object.setPrototypeOf(obj, proto) 直接修改已有对象的 [[Prototype]];会触发引擎对 obj 的隐藏类失效,显著影响性能,应避免在热路径中调用
  • 现代代码中,优先用 Object.create() 做一次性原型链搭建,而非动态改写

箭头函数、Object.assign() 和原型链无关

它们不参与原型链构建:

  • 箭头函数没有自己的 prototype 属性,不能用 new 调用,自然不产生原型链关系
  • Object.assign(target, ...sources) 只是浅拷贝可枚举自有属性,不会复制 [[Prototype]],也不会建立原型连接
  • 想“继承”多个对象的行为?得靠组合(mixin)、代理(proxy)或显式委托调用,不是靠原型链自动合并

真正容易被忽略的是:原型链只在读取属性时起作用;写入或删除操作始终发生在目标对象自身,不会顺着链向上。这意味着看似“继承”的属性,一旦被子对象赋值,就变成了自有属性,遮蔽了原型上的同名属性——这是很多动态覆盖逻辑出 bug 的根源。

text=ZqhQzanResources