[JS基础]prototype谁是谁祖宗
先看一段代码:
var a = function() {},
b = new a();
Function.prototype.isPrototypeOf(a);
Object.prototype.isPrototypeOf(a);
Object.prototype.isPrototypeOf(b);
Function.prototype.isPrototypeOf(b);
Object.prototype.isPrototypeOf(Function);
Function.prototype.isPrototypeOf(Object);
Object.constructor === Function;
Function.constructor === Function;
上面3-10行各返回的是true还是false?答案
如果你都想对了,就别浪费时间继续看了-_-
理解上面的问题,就要搞清谁是原型链的顶级及继承关系,参考ECMA5规范:
“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.”
“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.”
Object prototype object 标准内置对象(这里简称OPO) 是所有原型链的鼻祖,再向上就是null了
Function prototype object 标准内置对象(这里简成FPO) 是函数的原型对象,其__proto__为OPO
Function prototype及__proto__都指向FPO
所有其他内置构造函数其__proto__为FPO,prototype指向OPO,如:Object 构造函数 __proto__指向内置FPO,prototype指向OPO
函数实例也是一个实例对象(通过 new Function而来),和Object一样,内部prototype指向构造函数的protype属性,即FPO,prototype属性是创建时被添加(为OPO)用来作为构造函数而创建的 。
说的比较乱,画张图:

Function 用于实例函数对象,其prototype 为FPO,这样保证所有其他函数的继承FPO的属性方法
其他函数 用于实例普通对象,其prototype为OPO,保证每个对象实现都继承OPO的属性方法。
再来看看代码中用到的isPrototypeOf方法:
isPrototypeOf方法
O.isPrototypeOf(V)方法用于检查V的构造函数的原型是不是O,根据ECMA5规范
Object.prototype.isPrototypeOf (V)
When the isPrototypeOf method is called with argument V, the following steps are taken:
1. If V is not an object, return false.
2. Let O be the result of calling ToObject passing the this value as the argument.
3. Repeat
a. Let V be the value of the [[Prototype]] internal property of V.
b. if V is null, return false
c. If O and V refer to the same object, return true.
在检查时会有个向上遍历的过程,即:检测V的构造函数的原型是不是O,如果不是,接着检查V的构造函数的原型 的 构造函数原型 是不是O,直至原型为null,返回false。
理解了上面,再来看看开始的那段代码:
var a = function() {},
b = new a();
Function.prototype.isPrototypeOf(a); // a的__proto__为 FPO,返回true
Object.prototype.isPrototypeOf(a); // a的__proto__为 FPO,向上查找,FPO的 __proto__ === Object.prototype,返回true
Object.prototype.isPrototypeOf(b); // b的__proto__为OPO,返回true
Function.prototype.isPrototypeOf(b); // b的__proto__为OPO,向上查找,OPO的__proto__为null,返回false
Function.prototype.isPrototypeOf(Object); // F的__proto__为FPO,返回true
Object.prototype.isPrototypeOf(Function); // F的__proto__为FPO,向上查找,FPO的 __proto__ === Object.prototype,返回true
Object.constructor === Function; // true
Function.constructor === Function; // true