本文通过五句核心规则解析 JavaScript 原型链机制,阐述构造函数、原型对象与实例对象之间的指向关系。结合具体代码示例,逐步推导从 Game 构造函数到 Object 原型的完整继承链路,帮助开发者清晰理解 [[proto]] 属性与 prototype 属性的区别与联系,从而轻松掌握 JS 对象继承原理。
原型链核心机制概述
原型链是 JavaScript 中的一种核心机制。每个对象,包括原型对象本身,都包含一个内置的 [[proto]] 属性。该属性指向创建该对象的函数所对应的原型对象,即 prototype 属性。引入原型链的主要目的是为了实现对象间的继承功能。
理解原型链的五句口诀
掌握以下五句话,即可轻松理解 JavaScript 原型链的基本逻辑。
- Function 和 Object 均属于构造函数。
- 所有的构造函数均由 Function 通过 new 操作符创建(Function 自身也通过 new 自己来创建);所有的原型对象均由 Object 通过 new 操作符创建(Object 自身也通过 new 自己的原型对象来创建)。
- 每个构造函数都拥有 prototype 属性,该属性指向其对应的原型对象;每个实例对象都拥有 [[proto]] 属性。实例对象的 [[proto]] 属性值等于其构造函数的 prototype 属性值。
- 每个原型对象都天生拥有 constructor 属性,该属性指向其对应的构造函数。
- 底层规范规定 Object.prototype 的 [[proto]] 属性值为 null。
原型链构建过程详解
接下来,我们将结合一段简短代码,详细说明原型链的构建过程。
function Game(brand,name,price) {
this.price= price;
this.brand = brand;
this.name = name;
}
var g1 = new Game('EA','彩虹六号','200rmb');
首先,根据上述代码定义一个名为 Game 的构造函数。假设 Game 在堆内存中的地址为 0x100,并通过它 new 出一个实例对象 g1,g1 在堆内存中的地址为 0x200。构造函数 Game 拥有天生属性 prototype,指向其原型对象(该原型对象在堆内存中的地址为 0x300)。实例对象 g1 具有天生属性 [[proto]],指向其构造函数的原型对象;同时,原型对象拥有天生属性 constructor,指向其对应的构造函数。由此可得如下关系图:

其次,由于所有的原型对象都是由 Object(地址 0x400) new 出来的,因此地址为 0x300 的原型对象同时也是 Object 的一个实例对象。作为实例对象,它具备天生属性 [[proto]],指向其构造函数(即 Object)的原型对象(地址 0x500)。由于 Object 自身也是一个构造函数,它同样拥有天生属性 prototype,指向其原型对象(地址 0x500)。又因为所有的原型对象都是由 Object(0x400) new 出来的,所以地址为 0x500 的原型对象也是由 Object new 出来的。鉴于 0x500 是 Object 的原型对象,其天生属性 constructor 指向 Object。由于底层规定 Object.prototype 的 [[proto]] 等于 null,由此可得如下关系图:
3.
最后分析构造函数。由于所有的构造函数都是由 Function new 出来的,所以 Function(地址 0x600) new 出了自己、Object 以及 Game 这三个构造函数。这意味着这三个构造函数都是 Function 的实例对象,它们的 [[proto]] 均指向 Function 的 prototype(地址 0x700)。0x700 的天生属性 constructor 指向 0x600。由于 0x700 是由 Object new 出来的,所以 0x700 的 [[proto]] 指向 Object 的原型对象 0x500。最终我们得到完整的终极原型链图:

至此,关于 JavaScript 原型链的介绍已完成。如需了解更多相关内容,请搜索本站过往文章或继续浏览后续文章,感谢大家的支持!