简体   繁体   English

功能的JavaScript原型等效

[英]JavaScript prototypes equivalance for functions

I am reading JavaScript: Good parts by Douglas Crockford. 我正在阅读JavaScript:Douglas Crockford撰写的精彩文章。 I came across this following useful trick. 我遇到了以下有用的技巧。

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
};

Based on the above code snippet, what I understood is, as all functions are objects of Function and as the above function adds the 'method' method to prototype of Function , there will be a method method available on all functions. 基于上面的代码片段,我理解的是,由于所有函数都是Function对象,并且随着上述函数在Function原型中添加了'method'方法,因此所有方法上都将提供method方法。

var pfun = function(name){
    this.name = name;
};

Consider the following log statements 考虑以下日志语句

console.log(Function.prototype.isPrototypeOf(pfun));//true - Thats fine
console.log(pfun.prototype == Function.prototype);//false - why?

I couldn't understand why the above logs contradict each other. 我不明白为什么上面的日志相互矛盾。

Here pfun is a functions which has the method method available from its prototype. pfun是一个函数,该函数具有可从其原型获得的method方法。 So I can call the following. 所以我可以打以下电话。

pfun.method("greet",function(){
      console.log(this.name);
});

Now as method method runs, it adds the greet method to pfun 's prototype. 现在,当method方法运行时,它将greet方法添加到pfun的原型中。 If the above logs doesn't contradict each other, then greet method should be available to all functions. 如果以上日志彼此不矛盾,则greet方法应可用于所有功能。

My question is, why the above logs are contradicting each other? 我的问题是,为什么上面的日志相互矛盾?

They don't contradict each other. 他们彼此不矛盾。 Your pfun has a prototypal inheritance from Function , but it's not a reference to Function's prototype. 您的pfun具有Function的原型继承,但不是对Function的原型的引用。 It has its own prototype (that is derived from Function's one). 它有自己的原型(从Function的原型派生而来)。

So, when you ask if Function.prototype.isPrototypeOf(pfun) , you get true , because pfun 's prototype is derived from Function's one. 因此,当您询问是否Function.prototype.isPrototypeOf(pfun) ,您会得到true ,因为pfun的原型是从Function的原型派生的。 But when you ask if pfun.prototype is equal to Function.prototype , you get false , because it's false, pfun has its own prototype. 但是,当您询问pfun.prototype是否等于Function.prototype ,您会得到false ,因为它是假的, pfun有自己的原型。

The method greet is added only to the pfun 's prototype, and not to the Function 's one. greet方法仅添加到pfun的原型,而不添加到Function的原型。

But if you do: 但是,如果您这样做:

Function.prototype.method('greet', function() {
  console.log(this.name);
});

Then, all the function 's prototypes (that will be derived from Function.prototype ) will have the greet method in its prototype, because of the prototypal inheritance. 然后,由于原型继承,所有function的原型(将从Function.prototype派生)将在其原型中具有greet方法。

isPrototypeOf checks to see if an object is referenced by the internal [[Prototype]] property of another object. isPrototypeOf检查是否另一个对象的内部[[Prototype]]属性引用了一个对象。

All ECMAScript native functions inherit from Function.prototype therefore: 因此,所有ECMAScript本机函数都继承自Function.prototype

Function.prototype.isPrototypeOf(pfun))

returns true. 返回true。

Every native function created by the Function constructor has a default public prototype property that is a plain object (see ECMAScript §13.2 #16 ). 由Function构造函数创建的每个本机函数都有一个默认的公共原型属性,该属性是一个纯对象(请参阅ECMAScript§13.2#16 )。 So when you do: 因此,当您这样做时:

pfun.prototype == Function.prototype

you are comparing this plain object to Function.prototype 1 , which are different objects. 您正在将该简单对象与不同对象的Function.prototype 1进行比较。

This confusion is brought about in discussion because the public and private prototype properties are often only distinguished by the context in which the term is used. 由于公共和私有原型属性通常仅通过使用该术语的上下文来区分,因此在讨论中会引起这种混乱。 All native Functions have both, and only for the Function constructor are they the same object by default, ie 所有本机函数都具有两者,并且仅对于函数构造函数,默认情况下它们是同一对象,即

Object.getPrototypeOf(Function) === Function.prototype

returns true. 返回true。 This relationship can be established for other Objects, but it doesn't happen by default (and I can't think of an example or sensible reason to do it). 可以为其他对象建立这种关系,但是默认情况下不会发生这种关系(并且我认为这样做的示例或明智的理由)。

1 The Function.prototype object is a bit of an oddity. 1 Function.prototype对象有点奇怪。 It has an internal [[Class]] value of "function" and is callable, so in that regard it's a function. 它的内部[[Class]]值为“ function”并且可以调用,因此在这方面它是一个函数。 However, its internal [[Prototype]] is Object.prototype , so it can probably be called an instance of Object. 但是,其内部的[[Prototype]]Object.prototype ,因此它很可能称为Object的实例。 When called, it ignores all arguments and returns undefined . 调用时,它将忽略所有参数并返回undefined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM