ECMAScript@2021 - 关于原型链继承的解读

1,842 阅读2分钟

本文很短小很精悍

看了 ECMAScript@2021 最新的规范文稿, 开头部分关于原型对象和对象的关系解读, 非常赞, 原文用一种很通俗易懂的方式解释了构造函数, 共享方法, 原型对象三者之间的关系. 话不多说, 先上个图

图中的实现是显示原型链, 虚线是隐式原型链, 通过这张图我们可以把过去绕晕的原型链简单的表述出来

  1. CF 表示构造函数, 构造函数的 prototype 显示的指向 CFp
  2. cf1-cf5 是通过 CF 构造出来的对象, 他们共享 CFp 的属性 CFP1
  3. cf1-cf5 不共享 CF 的属性 P1 P2

用一句话来概括 通过构造函数构造的实例对象通过隐式原型链共享构造函数通过显示原型链绑定的原型对象所拥有的属性

让我们进一步来看待这种设计, 提出几个问题

  • 为什么构造函数自身的属性不直接共享给实例对象?
  • 什么是隐式原型链, 什么是显式原型链?

为什么构造函数自身的属性不直接共享给实例对象?

考虑到 ECMAScript 中 function 也是一种对象即 functionObject, 对象就会有属性, 但是对于构造函数来说, 它自身的属性可能是用于构造这个过程的, 并不希望共享或者暴露给构造出来的实例, 对于 functionObject 来说也不存在私有属性这种概念, 所以就有了原型对象用来区分构造函数自身的属性, 如果我们换个角度看, 构造函数的原型对象加上自身的属性, 是不是很像一个类中的 public 和 private 成员, public 会被继承, 而 private 不会. 至少从结果来看两者是相通的.

什么是隐式原型链, 什么是显式原型链?

所谓显式原型链, 其实就是 构造函数.prototype → 原型对象 → 构造函数.prototype → 原型对象... 而隐式原型链, 就是通过构造函数构造出来的实例 → __ proto __ → 原型对象

弄清楚这两个问题, 解决了我不定期的关于构造函数, 原型对象, 实例以及 prototype 和 __ proto __ 之间关系的一些困惑, 就像规范结尾说的, 不基于类, 但是提供更加灵活的抽象公共类方法的方式, 这就是 原型链继承大法

参考链接