需要的模式:创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__
上定义了p
(o.__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();