在JavaScript中,我想创建一个对象实例(通过new操作符),但将任意数量的参数传递给构造函数。这可能吗?
我想做的是这样的(但下面的代码不起作用):
function Something(){
// init stuff
}
function createSomething(){
return new Something.apply(null, arguments);
}
var s = createSomething(a,b,c); // 's' is an instance of Something
这个问题的答案
从这里的响应可以清楚地看出,没有内置的方法可以使用new操作符调用.apply()。然而,人们对这个问题提出了许多非常有趣的解决方案。
我更喜欢的解决方案是来自Matthew Crumley的这个(我修改了它来传递arguments属性):
var createSomething = (function() {
function F(args) {
return Something.apply(this, args);
}
F.prototype = Something.prototype;
return function() {
return new F(arguments);
}
})();
这种构造函数方法在使用或不使用new关键字时都有效:
function Something(foo, bar){
if (!(this instanceof Something)){
var obj = Object.create(Something.prototype);
return Something.apply(obj, arguments);
}
this.foo = foo;
this.bar = bar;
return this;
}
它假设支持Object。创建,但如果你支持旧的浏览器,你总是可以填充它。请参阅MDN上的支持表。
下面是一个JSBin,可以看到它在控制台输出中的作用。
看看CoffeeScript是如何做到的。
([a,b,c]…)
就变成:
var s;
s = (function(func, args, ctor) {
ctor.prototype = func.prototype;
var child = new ctor, result = func.apply(child, args);
return Object(result) === result ? result : child;
})(Something, [a, b, c], function(){});
这种构造函数方法在使用或不使用new关键字时都有效:
function Something(foo, bar){
if (!(this instanceof Something)){
var obj = Object.create(Something.prototype);
return Something.apply(obj, arguments);
}
this.foo = foo;
this.bar = bar;
return this;
}
它假设支持Object。创建,但如果你支持旧的浏览器,你总是可以填充它。请参阅MDN上的支持表。
下面是一个JSBin,可以看到它在控制台输出中的作用。