我知道用apply(obj,args)调用带有参数数组的函数的可能性; 有没有办法在创建函数的新实例时使用此功能?
我的意思是这样的:
function A(arg1,arg2){
var a = arg1;
var b = arg2;
}
var a = new A.apply([1,2]); //create new instance using an array of arguments
我希望你明白我的意思...... ^^^
感谢您的帮助!
解决!
我得到了正确的答案。为了使答案适合我的问题:
function A(arg1,arg2) {
var a = arg1;
var b = arg2;
}
var a = new (A.bind.apply(A,[A,1,2]))();
答案 0 :(得分:14)
var wrapper = function(f, args) {
return function() {
f.apply(this, args);
};
};
function Constructor() {
this.foo = 4;
}
var o = new (wrapper(Constructor, [1,2]));
alert(o.foo);
我们接受一个函数和参数,并创建一个函数,将该函数的参数应用于此作用域。
然后,如果您使用new关键字调用它,则会传递一个新的this
并返回它。
重要的是括号
new (wrapper(Constructor, [1,2]))
在包装器返回的函数上调用new关键字,其中为
new wrapper(Constructor, [1,2])
在包装函数上调用new关键字。
需要将其包装的原因是,您应用它的this
是使用new关键字设置的。需要创建一个新的this
对象并将其传递给一个函数,这意味着您必须在函数内调用.apply(this, array)
。
直播example
或者您可以使用ES5 .bind
方法
var wrapper = function(f, args) {
var params = [f].concat(args);
return f.bind.apply(f, params);
};
请参阅example
答案 1 :(得分:7)
使用ECMAscript 5,您可以:
function createInstanceWithArguments (fConstructor, aArgs) {
var foo = Object.create(fConstructor.prototype);
fConstructor.apply(foo, aArgs);
return foo;
}
答案 2 :(得分:6)
@Raynos的答案很有效,除了非ES5版本在实例化后缺少构造函数的原型。
这是我更新的cApply
方法:
var cApply = function(c) {
var ctor = function(args) {
c.apply(this, args);
};
ctor.prototype = c.prototype;
return ctor;
};
可以这样使用:
var WrappedConstructor = cApply(Constructor);
var obj = new WrappedConstructor([1,2,3]);
// or inline like this.
var obj2 = new (cApply(Constructor))([1,2,3]);
JSFiddle供参考。
答案 3 :(得分:3)
你可以讨论这些功能:
function A(arg1, arg2) {
// ...
}
function A12() {
A(1, 2);
}
你甚至可以建一家咖喱厂:
function A_curry() {
var args = arguments;
return function () {
A.apply(null, args);
};
}
答案 4 :(得分:3)
您可以使用Object.create()
构建新实例,然后在该实例上调用构造函数:
var args = [1,2,3];
var instance = Object.create(MyClass.prototype);
MyClass.apply(instance, args);
或单行:
var instance = MyClass.apply(Object.create(MyClass.prototype), args);
但不要忘记return this;
中的MyClass
这个单行解决方案。
如果你没有Object.create()
,那么写一个很简单:
Object.create = function (source){
var Surrogate = function (){};
Surrogate.prototype = source;
return new Surrogate();
};
您可以选择编写Function.newInstance()
或Function.prototype.newInstance()
功能:
Function.newInstance = function (fn, args){
var instance = Object.create(fn.prototype);
fn.apply(instance, args);
return instance;
};
所以var instance = Function.newInstance(MyClass, args);
。
注意:建议不要覆盖本机类。
答案 5 :(得分:0)
如果您将对象类名称存储在名为className
的变量中
var className = 'A'
根据this answer here,使用 ECMAScipt5 的Function.prototype.bind
方法,一切都变得非常干净和简单。
使用一组参数:
new ( Function.prototype.bind.apply( className, arguments ) );
或者使用参数列表:
new ( Function.prototype.bind.call( className, argument1, argument2, ... ) );
一行,不需要包装。
答案 6 :(得分:0)
我遇到了同样的问题,并且还希望保留目标对象的原型属性。看完答案后,我们想出了一个相当简单的解决方案。以为我可能会为任何未来的寻求者分享它:)
// Define a pseudo object that takes your arguments as an array
var PseudoObject = function (args) {
TargetObject.apply(this, args);
};
// if you want to inherit prototype as well
PseudoObject.prototype = new TargetObject();
// Now just use the PseudoObject to instantiate a object of the the OtherObject
var newObj = new PseudoObject([1, 2, 3]);