带有可选参数的JavaScript工厂

时间:2009-08-13 12:32:32

标签: javascript

问题是我需要创建传递类的新实例

有没有办法重写这个函数,所以它可以接受任意数量的参数?

function createInstance(ofClass, arg1, arg2, arg3, ..., argN){
  return new ofClass(arg1, arg2, arg3, ..., argN);
}

此函数应创建传递的类的实例。例如:

var SomeClass = function(arg1, arg2, arg3){
   this.someAttr = arg3;
   .....
}
SomeClass.prototype.method = function(){}

var instance = createInstance(SomeClass, 'arg1', 'arg2', 'arg3'); 

所以这应该是真的。

instance instanceof SomeClass == true  

现在,我只是将N限制在25,希望很少使用更多的参数。

2 个答案:

答案 0 :(得分:10)

其他答案都在正确的轨道上,但没有人提到你必须知道arguments Array这一事实。这是一种特殊的结构,其行为类似于Array

因此,在您像Array一样使用它之前,您可以将其转换为如下所示:

function createInstance(cls) {
    // This will use the slice function of the Array type, effectively converting
    // the arguments structure to an Array and throwing away the first argument,
    // which is cls.
    var args = Array.prototype.slice.call(arguments, 1);
    return cls.apply(this, args);
}

抱歉,我刚刚用constructor等复制了代码,并没有考虑它实际会做什么。我现在已经将它更新为你想要的。您会发现它在没有 new的情况下调用构造函数,因此您将无法获得相同的行为。但是,John Resig(jQuery的作者)wrote on this very issue

基于John Resig的文章,你有两种解决方法。更精细的解决方案对用户来说是最透明的,但这取决于您选择哪种解决方案。


如果您只打算支持具有Object.create功能的浏览器(现在与三年前的比例相当大),这是一个“完美”的解决方案:

function createInstance(cls) {
    var obj = Object.create(cls.prototype);

    var args = Array.prototype.slice.call(arguments, 1);
    cls.apply(obj, args);

    return obj;
}

来自new cls(x)createInstance(cls, x)的结果对象应该相同。

答案 1 :(得分:4)

始终有arguments array