0

我有一个 Mootools 课程:

var Foo = new Class({
    initialize: function(param1, param2) {
        // do stuff
    }
});

初始化 Foo 的值在一个数组中:

a = ['value1', 'value2'];

如何使用 from 的值a来初始化 的实例Foo

4

2 回答 2

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

于 2013-01-28T21:27:36.363 回答
2

没有直接的方法来调用带有要扩展的参数数组的构造函数,就像使用Function.apply.

如果你用 来创建你的类的一个新实例new Foo(),MooTools 调用构造函数 ( initialize) 隐式地传递你调用 Foo() 的参数。但是,initialize它仍然作为实例的方法存在,因此您可以像这样简单地“再次”调用它:

var myFoo = new Foo();
myFoo.initialize.apply(myFoo, ['value1', 'value2']);

但这确实是一种不好的做法,因为构造函数通常不会被调用两次,而且您很可能会遇到问题。

另一种方法是在不让 MooTools 调用构造函数的情况下创建实例。首先,您需要一个普通实例,然后initialize作为实例的方法调用。这是相当骇人听闻的,但可以这样实现:

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 不调用构造函数的开关。

于 2013-01-28T15:43:34.270 回答