(七) 深入理解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.
Function.prototype
像普通函数一样可以调用,但总是返回undefined
。- 普通函数实际上是
Function
的实例,即普通函数继承于Function.prototype
。func.__proto__ === Function.prototype
。 Function.prototype
继承于Object.prototype
,并且没有prototype
这个属性。func.prototype
是普通对象,Function.prototype.prototype
是null
。- 所以,
Function.prototype
其实是个另类的函数,可以独立于/先于Function
产生。