带有可选参数的JavaScript工厂

4 javascript

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

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

function createInstance(ofClass, arg1, arg2, arg3, ..., argN){
  return new ofClass(arg1, arg2, arg3, ..., argN);
}
Run Code Online (Sandbox Code Playgroud)

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

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

var instance = createInstance(SomeClass, 'arg1', 'arg2', 'arg3'); 
Run Code Online (Sandbox Code Playgroud)

所以这应该是真的.

instance instanceof SomeClass == true  
Run Code Online (Sandbox Code Playgroud)

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

Bli*_*ixt 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);
}
Run Code Online (Sandbox Code Playgroud)

对不起,我刚刚用constructor等等复制了代码,并没有考虑它实际会做什么.我现在已经将它更新为你想要的.你会发现它没有 调用构造函数new,所以你不会得到相同的行为.然而,John Resig(jQuery的作者)在这个问题上写道.

因此,基于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;
}
Run Code Online (Sandbox Code Playgroud)

从两者得到的对象new cls(x)createInstance(cls, x)应该是相同的.