javascript中什么是原型链_它如何实现继承【教程】

9次阅读

原型链是javaScript中实现继承的唯一底层机制,通过对象的[[prototype]]隐式链接到构造函数的prototype,形成属性查找路径,终点为Object.prototype,其[[Prototype]]为NULL

javascript中什么是原型链_它如何实现继承【教程】

javascript 中没有传统面向对象语言里的“类继承”,原型链是实现对象间属性和方法共享的唯一底层机制。

原型链是怎么形成的

每个对象内部都有一个隐式原型 [[Prototype]](可通过 __proto__ 访问,但不推荐直接使用),它指向该对象的构造函数的 prototype 对象。当访问一个对象上不存在的属性时,js 引擎会沿着 [[Prototype]] 一层层向上查找,直到找到或抵达 null —— 这条查找路径就是原型链。

常见错误现象:obj.toString() 能用,但 obj 自身并没有定义 toString;这是因为 Object.prototype.toString 在原型链顶端。

  • 所有普通对象的原型链终点都是 Object.prototype,它的 __proto__null
  • functionArraydate 等内置构造函数的 prototype 对象,本身也是普通对象,所以也继承自 Object.prototype
  • 手动设置 obj.__proto__ = null 会切断原型链,导致失去所有继承方法(如 hasOwnProperty 不可用)

如何用原型链实现继承

核心是让子类型实例的 [[Prototype]] 指向父类型的 prototype 对象。最直接的方式是修改子构造函数的 prototype

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

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; // 修复 constructor 指向

注意点:

  • Object.create(Parent.prototype) 比直接赋值 Child.prototype = Parent.prototype 安全,后者会让子类修改影响父类原型
  • 必须手动恢复 constructor,否则 new Child().__proto__.constructor 会指向 Parent
  • 不调用 Parent.call(this, ...) 的话,子实例无法获得父类实例属性(如 this.name

为什么现代代码很少手写原型链继承

因为容易出错且可读性差:漏掉 constructor 修复、忘记 call 父构造函数、误用 __proto__ 导致性能问题,都是高频坑。

es6 后标准做法是用 class + extends,它只是原型链的语法糖:

class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { super(name); this.age = age; } }

这背后仍是操作 Child.prototype.__proto__ = Parent.prototype,但引擎自动处理了构造函数修复、super 绑定等细节。

真正需要关注原型链的场景,通常是调试时看 instanceof 判断、理解 hasOwnPropertyin区别,或者封装低层工具函数(如深克隆需遍历原型链)。

原型链本身很简单,难的是在各种继承写法(寄生组合、ES6 class、Object.setPrototypeOf 动态修改)中保持原型关系清晰——一旦中间某环被意外覆盖或设为 null,继承就静默失效,而且很难一眼发现。

text=ZqhQzanResources