原型链一直是个 很绕的问题,再来总结一下吧。
用例子来切入吧:
var F = function(){};
Object.prototype.a = function(){
console.log('aa');
};
Function.prototype.b = function(){
console.log('bb');
};
var f = new F();
F.a(); //aa
F.b(); //bb
f.a(); //aa
f.b(); // b not a function
分析前提:
- 实例对象只有
_proto_
属性,函数对象才有prototype
属性 - Function、Object 是Js自带的函数对象
- 函数的默认原型对象是Object的实例
注意:
原型链的形成靠的是 _proto_
,而不是 prototype
属性
来仔细分析一下:
- 实例对象的
_proto_
指向原型对象,构造函数的prototype
指向原型对象,即实例对象的_proto_
指向构造函数的prototype
。
f._proto_ = F.prototype
2.构造函数的创建默认调用了 new Function 来创建
F._proto_ = Function.prototype
- 函数的默认原型对象是Object的实例
Function.prototype._proto_ = Object.prototype
4.由上面的推论可得
f._proto_._proto_ = Object.prototype
- 所以f、 F的原型链如下:
f -----> F.prototype -----> Object.prototype -----> null
F -----> Function.prototype -----> Object.prototype -----> null
经过如上分析,得到的结果就是:
f 只能访问到 a
F 可以访问到 a ,b
其实有种 很简单的解释,因为 f不是个函数,所以原型上没有Function。这句话也比较好理解吧。
那下面放一张原型链的图(盗的图)吧: