(七) 深入理解js中的原型与原型链

通过一些问题引发的思考

1. instanceof判断的本质

表达式: A instanceof B

我们都知道: instanceof 用作判断某个对象是否是某个对象类型的实例

当我们弄懂了原型链之后, 再来看这句话: 谁是谁的实例, 也就是说前者的__proto__属性的值是后者的prototyp属性的值 !

我们来看一下究竟是不是这样:

function fn() { }
console.log(fn instanceof Function);    // true
console.log(fn.__proto__ === Function.prototype);   //true

console.log(fn instanceof Object);    // true
console.log(fn.__proto__ === Object.prototype);   // false
console.log(fn.__proto__.__proto__ === Object.prototype);   // true

再来看一下最后两行代码: 发现fn._proto_ 并不等于Object.prototype, 而是fn.__proto__.__proto__与Object.prototype的值相同,为什么是这样呢? 不是说前者的__proto__属性的值是后者的prototyp属性的值吗, 这里为什么行不通呢, 对比原型链的示意图, 我们发现, instanceof 判断的本质其实是 : 判断A的原型链上是否有B的原型, 而并非一开始所说

结论1: instanceof判断对象A的原型链上是否有对象B的原型


2. JS中一切函数都是Function的实例吗 ?

当我们定义了一个构造函数后, 需要通过new关键字来创建实例, 既然 new 后面跟的是一个构造函数,那么:

... = new Array()

... = new Object()

... = new Function()

// 以及两个特殊对象 正则(RegExp)和日期(Date)

那么这些函数都是Function构造函数创建的吗?

console.log(Object instanceof Function);    // true
console.log(Array instanceof Function);     // true
console.log(Function instanceof Function);  // true

也就是说, Function.prototype在所有函数 (包括Function本身) 的原型链上,也就说明了 : JS中一切函数都是Function的实例

结论2: JS中一切函数都是Function的实例


3. Function.prototype的问题

console.log(typeof Function.prototype);     // 'function'

第一行代码我们看到 Function.prototype 的类型显式为函数对象, 既然是函数对象,那么也就应该有prototype属性,同时也是Function的实例,真的是这样吗?

console.log(Function.prototype.prototype);    	// undefined

规范里说道:

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

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

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.

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.prototypefunc.__proto__ === Function.prototype
  3. Function.prototype继承于Object.prototype并且没有prototype这个属性func.prototype是普通对象,Function.prototype.prototypenull
  4. 所以,Function.prototype其实是个另类的函数,可以独立于/先于Function产生。

posted @ 2021-07-26 14:19  只猫  阅读(103)  评论(0编辑  收藏  举报