我有一个Mootools课程:
var Foo = new Class({
initialize: function(param1, param2) {
// do stuff
}
});
初始化Foo的值在数组中:
a = ['value1', 'value2'];
如何使用a
中的值初始化Foo
的实例?
答案 0 :(得分:3)
我会延长课程的原型,所以它不在乎(见Felix的回答)。
var Foo = new Class({
initialize: function(param1, param2) {
console.log(param1, param2);
}
});
(function(){
var oldFoo = Foo.prototype.initialize;
Foo.implement({
initialize: function(){
var args = typeOf(arguments[0]) == 'array' ? arguments[0] : arguments;
return oldFoo.apply(this, args);
}
});
}());
new Foo(['one', 'two']); // one two
new Foo('three', 'four'); // three four
它涉及较少的黑客攻击,并且可能比创建特殊的构造函数抽象更容易理解/维护。
如果可以的话,你甚至可以做到
var Foo2 = new Class({
Extends: Foo,
initialize: function () {
var args = typeOf(arguments[0]) == 'array' ? arguments[0] : arguments;
this.parent.apply(this, args);
}
});
new Foo2(['one', 'two']);
new Foo2('three', 'four');
因此,在不修改父原型和期望的情况下进行非常清晰的抽象 - 并保持讨厌的SOLID原则让人感到高兴:D
答案 1 :(得分:2)
没有直接的方法来调用具有要扩展的参数数组的构造函数,就像使用Function.apply
一样。
如果使用new Foo()
创建类的新实例,MooTools会调用构造函数(initialize
)隐式传递您调用Foo()的参数。但是,initialize
仍然作为实例的方法存在,因此您可以简单地“再次”调用它:
var myFoo = new Foo();
myFoo.initialize.apply(myFoo, ['value1', 'value2']);
但这实际上是不好的做法,因为构造函数通常不会被调用两次,很可能会遇到问题。
另一种方法是在不让MooTools调用构造函数的情况下创建实例。首先,您需要一个普通实例,然后调用initialize
作为实例的方法。这是相当hackish,但可以像这样实现:
var Foo = new Class({
initialize: function(param1, param2) {
this.param1 = param1;
this.param2 = param2;
},
getParams: function() {
console.log(this.param1 + ', ' + this.param2);
}
});
Class.createInstance = function(klass, args) {
klass.$prototyping = true;
var inst = new klass();
klass.$prototyping = false;
inst.initialize.apply(inst, args);
return inst;
}
var myFoo = Class.createInstance(Foo, ['a', 'b']);
// returns "a, b"
myFoo.getParams();
$prototyping
是MooTools不能调用构造函数的开关。