需要的模式:创build一个新的对象,返回一个可执行的function,并从原型inheritance

情况1 – 一切正常:

var AwesomeObject = function() { var self = this; self.whatstuff = 'really awesome'; } AwesomeObject.prototype.doStuff = function() { var self = this; console.log('i did '+self.whatstuff+' stuff'); return self; } var awesome = new AwesomeObject(); //returns a new AwesomeObject awesome.doStuff(); // prints 'i did really awesome stuff' on the console 

现在我想要它甚至awesomer:

 var AwesomeObject = function() { var f = function() { console.log('i am awesome'); } var self = f; self.whatstuff = 'really awesome'; return self; } AwesomeObject.prototype.doStuff = function() { var self = this; console.log('i did '+self.whatstuff+' stuff'); return self; } var awesome = new AwesomeObject(); //returns the interal f object awesome(); // prints 'i am awesome' awesome.doStuff(); // throws an error 

新的AwesomeObject应该返回一个可执行的函数本身,所以我可以说'真棒();“

但我希望它也inheritance了AwesomeObject.prototype

添加self.prototype = AwesomeObject.prototype; 没有帮助。

 var AwesomeObject = function() { var f = function() { console.log('i am awesome'); } var self = f; self.whatstuff = 'really awesome'; self.prototype = AwesomeObject.prototype; return self; } 

好吧,我可以复制AwesomeObject.prototype函数 – 一个接一个 – 进入f的范围

 var AwesomeObject = function() { var f = function() { console.log('i am awesome'); } var self = f; self.whatstuff = 'really awesome'; self.doStuff = function() { AwesomeObject.prototype.doStuff.apply(self,arguments); } return self; } 

但我认为必须有更好的方式,更好的模式,这是什么?

这个问题使我疯狂,帮助将非常感激。

一般来说:如何创build一个函数对象

  • 可以用新的创build
  • 返回一个可以执行的函数对象
  • inheritance给定原型的所有属性和方法

有没有办法?

thx弗朗茨

一个非常简单的模式是一个工厂。

 var AwesomeObject = (function() { var AwesomeObject = function() { this.whatstuff = 'really awesome'; }; AwesomeObject.prototype.doStuff = function() { console.log('i did ' + this.whatstuff + ' stuff'); return this; }; return function() { var o = new AwesomeObject(); var f = function() { console.log("I am awesome"); }; for (var k in o) { f[k] = o[k]; } return f; }; })(); var foo = AwesomeObject(); foo(); foo.doStuff(); 

现场示例 。

这个想法是,你把你的function和对象分成两件事。 您的对象存在于您的函数的本地范围中,并且该函数可以使用该对象。

对象本身完全通过原型inheritance。

关键是将对象的所有属性/方法转发到函数上。

这是最干净的解决scheme。

当一个属性被解决时,你可能知道原型链是遍历的。 但是,如果你有一个awesome的对象,并尝试评估awesome.doStuff ,那么awesome.prototype将永远不会被查询属性。 你可以在你的例子中validation这个, "doStuff" in awesome => false "doStuff" in awesome.prototype => true

所以你正在做的不是改变awesome的隐含属性,你正在改变它的原型,这意味着通过做new awesome创build的任何对象将具有该属性。 validation: "doStuff" in new awesome() => true 。 这是有道理的,因为在使用f/awesome时无法区分构造函数或常规函数。

parsing对象o上的属性p的过程大致如下:

  • 检查是否在o上定义了p
  • 检查是否在o.__proto__上定义了po.__proto__用法是非标准的,但是广泛实现,除了上次我检查过的jscript,它现在已经在SpiderMonkey中被弃用了)
  • 检查是否在o.constructor.prototype上定义了o.constructor.prototype
  • 检查是否在o.constructor.prototype.prototype上定义了o.constructor.prototype.prototype
  • 等等

所以一个解决scheme就是简单地设置o.__proto__ = AwesomeClass.prototype 。 把__proto__想象成一个对象和原型之间隐藏的中介对象。 每个实例接收自己的唯一__proto__对象。 但是像我说的那样,这个已经被废弃了,并且是非标准的。

我们也可以在Function.prototype设置值,但是会覆盖其他的Function属性并影响所有的Function实例。 我们不要那个。

那剩下什么了? 事实并非如此。 没有办法设置一个对象的完整原型,同时保留它的inheritance原型。 您需要遍历原型并复制所有属性。 幸运的是,这将允许instanceof在处理构造函数链时按预期工作,并允许正确地inheritance/覆盖属性。

问题是,没有内build的方法来将对象的属性复制到另一个对象中,并且没有标准的方法来改变对象的原型链ad-hoc( __proto__ )。

所以使用__proto__ ,或者遍历原型。

我不认为有这样做的好方法。 我会重新devise你的程序来避免它。

但是,这是一个糟糕的依赖平台的解决scheme(在使用非标准__proto__属性的V8上工作):

 var PrototypeToBeInherited = {'inheritedProperty': 'inheritedPropertyValue'}; f = function() { return "result"; }; f.__proto__ = PrototypeToBeInherited; f() => "result"; f.inheritedProperty => "inheritedPropertyValue" 

为了您的要求,它必须创build“新”,只是包装在function:

 F = function() { return f; } var instance = new F();