我所理解的 Javascript prototype chain
Objective-C 中的类继承关系图

对 iOS 开发熟悉的同学应该都知道,OC 中有个经典的 metaclass / 和类继承关系图
Javascript 中的 prototype chain
而在 JS 中, 也同样存在类似的 prototype chain, 如下图所示

图的来源是 https://azole.medium.com/javascript-prototype-chain-ee5a90f6fa5e
这个图看起来比较复杂,我们试着来拆解一下
prototype 和 proto 的区别
-
prototype:
- 仅存在于函数对象上(构造函数)
- 用于实现基于原型的继承
- 示例:
Function.prototype,Array.prototype
-
__proto__:
- 存在于所有对象实例上
- 指向构造函数的 prototype 属性
- 现代代码建议使用
Object.getPrototypeOf()
Object 和 Function
在 JavaScript 中,Object 和 Function 有着特殊的相互关系:
-
Object:
- 是所有对象的基类
- 通过
Object.prototype提供基础方法 - 用
{}创建的对象都继承自Object.prototype - Object.prototype.__proto__是 null,为继承关系的终点
-
Function:
- 是函数的构造函数
- 所有函数都是
Function的实例 - 包含
call(),apply()等方法 - 所有构造函数的 __proto__ 都指向 Function.prototype
Function 和 Object 既是函数也是对象
关键关系:
-
prototype.constructor
Function.prototype.constructor === FunctionObject.prototype.constructor === Object
-
Function 的 prototype 和 __proto__
Function.__proto__ === Function.prototype
-
Object 和 Function 的关系
Function.prototype.__proto__ === Object.prototypeObject.__proto__ === Function.prototype
prototype chain 图示
- 图 1:

-
图 2 (加入 obj):

-
图 3 (加入 Foo):

-
图 3 (加入 foo):

个人的理解和总结
- 对象存在__proto__
- 函数存在 prototype
- 函数同时是对象, 所以函数也有__proto__
- 函数的 prototype.constructor 指向函数本身
- 函数的__proto__ 指向 Function.prototype
- __proto__ 是继承关系的关键, 当访问对象属性时,JS 引擎会沿着 __proto__ 链向上查找
- Object.prototype.__proto__ 指向 null, 为继承关系的终点
- 当使用 new 创建实例时,实例的 __proto__ 会指向构造函数的 prototype