JavaScript原型功能的等效性

时间:2015-10-14 03:35:24

标签: javascript prototype

我正在阅读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方法应该可用于所有函数。

我的问题是,为什么上述日志相互矛盾?

2 个答案:

答案 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