一、题目
我们先看一道题目
var F = function() {}; Object.prototype.a = function() { console.log('a'); }; Function.prototype.b = function() { console.log('b'); } var f = new F(); f.a(); f.b(); F.a(); F.b();
二、解题关键
借用网络上的图片,看起来有点绕,待我们一点一点理解。有以下几点:
三、图片解析
-
__proto__
是原型链的链接 - 通过
__proto__
查找到prototype
,prototype
是原型的关键字 -
var f = new F()
f: 是实例对象 F: 是构造函数 f通过__proto__
找到F.prototype
,所以f.__proto__ === F.prototype
- 构造器的原型属于对象 Object ,也就是说
F.prototype
是new object
出来的。所以F.prototype
通过__proto__
可以找到Object.prototype
即:F.prototype.__proto__ === Object.Prototype
-
function Function()
是函数构造器Function.__proto__ === Function.prototype
Function.prototype
是对象,所以Function.prototype.__proto__ === Object.prototype
- 终极:
Objecy.prototype.__proto__ === null
四、题目解析
再回过头来看上面的题目
-
f.a()
,f 是实例对象, f没有a属性,通过f.__proto__
找到原型F.prototype
,F.prototype
上也没有a属性,继续通过F.prototype.__proto__
找到Object.prototype
,发现a属性,所以输出a -
f.b()
,同理找到Object.prototype
,发现Object.prototype
也没有b属性,继续通过__proto__
查找 到了null,所以b函数不存在,浏览器报错。 则 F.a(),F.b()也不会执行 - 若注释了
f.b()
,执行F.a()
。F是函数,F上没有a属性,通过__proto__
找到Function.prototype
,发现Function.prototype
没有a属性,继续通过__proto__
,找到Object.prototype
,找到了a属性,输出a - 若注释了
f.b()
,执行F.b()
。同理找到Function.prototype
,发现b属性,输出b
五、参考资料
如果有理解不对的地方,欢迎大佬指正!