我所理解的 Javascript prototype chain

Objective-C 中的类继承关系图

class-relation-oc

对 iOS 开发熟悉的同学应该都知道,OC 中有个经典的 metaclass / 和类继承关系图

Javascript 中的 prototype chain

而在 JS 中, 也同样存在类似的 prototype chain, 如下图所示 js-proto-chain

图的来源是 https://azole.medium.com/javascript-prototype-chain-ee5a90f6fa5e

这个图看起来比较复杂,我们试着来拆解一下

prototype 和 proto 的区别

  1. prototype

    • 仅存在于函数对象上(构造函数)
    • 用于实现基于原型的继承
    • 示例:Function.prototype, Array.prototype
  2. __proto__:

    • 存在于所有对象实例上
    • 指向构造函数的 prototype 属性
    • 现代代码建议使用Object.getPrototypeOf()

Object 和 Function

在 JavaScript 中,Object 和 Function 有着特殊的相互关系:

  1. Object:

    • 是所有对象的基类
    • 通过Object.prototype提供基础方法
    • {}创建的对象都继承自Object.prototype
    • Object.prototype.__proto__是 null,为继承关系的终点
  2. Function:

    • 是函数的构造函数
    • 所有函数都是Function的实例
    • 包含call(),apply()等方法
    • 所有构造函数的 __proto__ 都指向 Function.prototype


    Function 和 Object 既是函数也是对象

关键关系:

  1. prototype.constructor

    • Function.prototype.constructor === Function
    • Object.prototype.constructor === Object
  2. Function 的 prototype 和 __proto__

    • Function.__proto__ === Function.prototype
  3. Object 和 Function 的关系

    • Function.prototype.__proto__ === Object.prototype
    • Object.__proto__ === Function.prototype

prototype chain 图示

  • 图 1:

js-proto-chain

  • 图 2 (加入 obj): js-proto-chain

  • 图 3 (加入 Foo): js-proto-chain

  • 图 3 (加入 foo): js-proto-chain

个人的理解和总结

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