我正在阅读JavaScript:道格拉斯·克罗克福德的优秀作品。我偶然发现了这个有用的技巧。
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
}
};
基于上面的代码片段,我理解的是,因为所有函数都是Function
的对象,并且上面的函数将'method'
方法添加到Function
的原型中,所以是所有功能都可用的method
方法。
var pfun = function(name){
this.name = name;
};
考虑以下日志声明
console.log(Function.prototype.isPrototypeOf(pfun));//true - Thats fine
console.log(pfun.prototype == Function.prototype);//false - why?
我无法理解为什么上述日志相互矛盾。
此处pfun
是一个函数,其原型中提供了method
方法。所以我可以打电话给以下。
pfun.method("greet",function(){
console.log(this.name);
});
现在,当method
方法运行时,它会将greet
方法添加到pfun
的原型中。如果上述日志不相互矛盾,则greet
方法应该可用于所有函数。
我的问题是,为什么上述日志相互矛盾?
答案 0 :(得分:0)
他们互不矛盾。您的pfun
具有来自Function
的原型继承,但它不是对函数原型的引用。它有自己的原型(源自Function&#39)。
因此,当您询问是否Function.prototype.isPrototypeOf(pfun)
时,您会得到true
,因为pfun
的原型来自于函数的原型。但当您询问pfun.prototype
是否等于Function.prototype
时,您会得到false
,因为它是假的,pfun
有自己的原型。
方法greet
仅添加到pfun
的原型中,而不是Function
的原型。
但如果你这样做:
Function.prototype.method('greet', function() {
console.log(this.name);
});
然后,由于原型继承,所有function
原型(将从Function.prototype
派生)将在其原型中具有greet
方法。 / p>
答案 1 :(得分:0)
isPrototypeOf检查另一个对象的内部[[Prototype]]
属性是否引用了一个对象。
所有ECMAScript本机函数都继承自 Function.prototype :
Function.prototype.isPrototypeOf(pfun))
返回true。
Function构造函数创建的每个本机函数都有一个默认的public prototype 属性,它是一个普通对象(参见ECMAScript §13.2 #16)。所以当你这样做时:
pfun.prototype == Function.prototype
您正在将此普通对象与 Function.prototype 1 进行比较,它们是不同的对象。
这种混淆在讨论中引起,因为公共和私有原型属性通常仅通过使用该术语的上下文来区分。所有本机函数都有,并且只有函数构造函数默认它们是相同的对象,即
Object.getPrototypeOf(Function) === Function.prototype
返回true。这种关系可以为其他对象建立,但默认情况下不会发生(我不能想到这样做的例子或明智的理由)。
1 Function.prototype 对象有点奇怪。它的内部[[Class]]
值为"函数"并且可以调用,所以在这方面它是一个功能。但是,其内部[[Prototype]]
是 Object.prototype ,因此它可能被称为Object的实例。调用时,它会忽略所有参数并返回 undefined 。