前两天从网上看到一个题目,大致内容如下:
var F=function(){}; Function.prototype.a=function(){console.log("a");}; Object.prototype.b=function(){console.log("b");}; var f=new F(); f.b(); f.a();
初看这道题,觉得很简单,应该会输出 "b" 和 "a"吧,但是实际运行起来,不是那么回事,实际结果是:第二个函数报错了,没有找到a的定义。怎么回事?
其实,这道题目主要考察大家对原型链的理解。我们知道,当一个对象其中找不到某个属性时,会沿着其原型链向上查看其它对象中是否有该属性,直到找到为止,如果都没有找到的话,这时就像上面的题目一样会报错了。
原型链是怎么构建起来的呢? 在js的世界里,万物皆对象,每个对象中都有一个私有的__proto__属性,该属性用来标识其上一级的原型对象,就这样通过这个属性把整个原型链构建起来。
而题目中的原型链又是怎样的呢?从原型链的最顶端开始(就是当前的对象f)构建原型链。我们知道__proto__属性值其实就是当前对象构造函数的prototype属性值,因此就有下面的等式:
f.__proto__===F.prototype;//f的构造函数是 F
F.prototype.__proto__===Object.prototype; //F.prototype的构造函数是Object
同理,总结原型链如下:
f---->F.prototype---->Object.prototype---->null F---->Function.prototype---->Object.prototype---->null
因此,f.a不存在就显而易见了。
时间: 2024-11-08 15:14:10