4 min read

原型链深入

img

第一种

Object.proto === Function.prototype

看完上面一个很常见的 原型链 图示,看下面的例子:

let obj = {};
obj.__proto__ === Object.prototype; // return true

OK,结果显而易见是没有问题的;声明一个对象,对象的隐式原型 [[Prototype]](内部属性,我们并不能访问到,所以使用 __proto__ 来访问)与它的构造函数的原型连接起来。

那么看下个例子:

Object.__proto__ === Object.prototype; // return false

可能会觉得有些诧异,为什么Object的原型链指向了自己的原型??

其实这里的Object是构造函数;也就是说,它是一个函数,而不是一个纯对象。(这里说的对象是数据类型)

那么一个函数的原型链首先就会指向 Function.prototype了。

规范是这么写的

The value of the [[Prototype]] internal property of the Object constructor is the standard built-in Function prototype object.

The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]] internal property is "Object", and the initial value of the [[Extensible]] internal property is true.

所以:

Object.__proto__ === Function.prototype; // return true

第二种

Function.proto === Function.prototype

让我们先来看下这个例子的结果:

Function.__proto__ === Function.prototype // return true

会不会有些疑惑?

Function 的__proto__指向了它本身的原型 ??因为我们普遍的认知就是:实例对象的__proto__属性指向它的构造函数的原型对象(prototype)。

规范这样说:

Function.prototype是个不同于一般函数(对象)的函数(对象)

  1. The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.

  2. The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object (15.2.4). The initial value of the [[Extensible]] internal property of the Function prototype object is true.

  3. The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.

解释

  1. Function.prototype 像普通函数一样可以调用,但总是返回 undefined
  2. 普通函数实际上是Function的实例,即普通函数继承于Function.prototype。例如:func.__proto__ === Function.prototype
  3. Function.prototype 继承于 Object.prototype,并且没有prototype这个属性(函数都有prototype属性,除了Function.prototype)。func.prototype 是普通对象,Function.prototype.prototypenull

所以,Function.prototype 其实是个另类的函数,可以独立于/先于 Function 产生。

回归到上面的疑惑,为什么 Function.prototypeFunction.__proto__ 是同一个对象?

  1. 首先,Function 本身是一个函数
  2. Function.prototype 是所有 function 的原型(包括Function自己)。

所以疑惑可以这样解释:

Function.prototypeFunction.__proto__ 相同不代表Function这个函数是由自身创建的。先有了Function.prototype这个函数对象,然后才有了 function Function() 而已。然后其他的构造函数都是 function Function() 生成的。

Conclusion

  • 先有 Object.prototype(原型链顶端),Function.prototype 继承 Object.prototype 而产生,最后,Function 和 Object 和其它构造函数继承 Function.prototype 而产生

  • 每个函数都有 prototype 属性,除了 Function.prototype

不足&疑惑之处,欢迎讨论