Javascript-使用参数数组创建实例
我知道可以使用参数数组调用函数,参数为apply(obj,args); 在创建函数的新实例时,是否有方法使用此功能 我的意思是这样的:Javascript-使用参数数组创建实例,javascript,Javascript,我知道可以使用参数数组调用函数,参数为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 var WrappedConstructor = cApply(Construct
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
var WrappedConstructor = cApply(Constructor);
var obj = new WrappedConstructor([1,2,3]);
// or inline like this.
var obj2 = new (cApply(Constructor))([1,2,3]);
我希望你明白我的意思^^^
谢谢你的帮助
解决了强>
我得到了正确的答案。为了使答案符合我的问题:
function A(arg1,arg2) {
var a = arg1;
var b = arg2;
}
var a = new (A.bind.apply(A,[A,1,2]))();
您可以设置以下功能:
function A(arg1, arg2) {
// ...
}
function A12() {
A(1, 2);
}
你甚至可以建立一个咖喱工厂:
function A_curry() {
var args = arguments;
return function () {
A.apply(null, args);
};
}
我们获取一个函数和参数,并创建一个函数,将这些参数应用于具有此作用域的函数
然后,如果您使用new关键字调用它,它将传入一个新的freshthis
并返回它
重要的是括号
new(包装器(构造函数[1,2]))
对包装器返回的函数调用new关键字,其中
新包装器(构造函数[1,2])
调用包装函数上的new关键字
需要对其进行包装的原因是,应用它的此
设置了新关键字。需要创建一个新的this
对象并将其传递到函数中,这意味着您必须在函数中调用。apply(this,array)
生活
或者,您可以使用ES5方法
请参见使用ECMAscript 5,您可以:
function createInstanceWithArguments (fConstructor, aArgs) {
var foo = Object.create(fConstructor.prototype);
fConstructor.apply(foo, aArgs);
return foo;
}
@Raynos answer运行良好,除了非ES5版本在实例化后缺少构造函数的原型 以下是我更新的
cApply
方法:
var cApply = function(c) {
var ctor = function(args) {
c.apply(this, args);
};
ctor.prototype = c.prototype;
return ctor;
};
可以这样使用:
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
var WrappedConstructor = cApply(Constructor);
var obj = new WrappedConstructor([1,2,3]);
// or inline like this.
var obj2 = new (cApply(Constructor))([1,2,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);
但是别忘了返回这个代码>在MyClass
中,通过此单行解决方案
如果没有Object.create()
,那么编写一个非常简单:
Object.create = function (source){
var Surrogate = function (){};
Surrogate.prototype = source;
return new Surrogate();
};
您可以选择编写函数.newInstance()
或函数.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)代码>
注意:不建议重写本机类。如果将对象类名存储在名为className
的变量中,该怎么办
var className = 'A'
因此,使用ECMAScipt5的函数.prototype.bind
方法,一切都变得非常干净和简单
使用一系列参数:
new ( Function.prototype.bind.apply( className, arguments ) );
或使用参数列表:
new ( Function.prototype.bind.call( className, argument1, argument2, ... ) );
一行代码,不需要包装器。我也有同样的问题,还想保留目标对象的原型属性。在看了答案之后,我想到了一个相当简单的解决方案。我想我也可以把它分享给任何未来的探索者:)
非常好+1在您的基础上,可能需要让包装器
使用您想要的标识符将函数返回到一个变量,这样您就可以从该变量调用new
,从而给出您期望的instanceof
结果。。。或者不是(对我的朋友)。睡了一会儿,我发现我没有抓住问题的重点。谢谢,这真的很好。但问题是,生成的对象不是构造函数类型。有什么方法可以避免这种情况吗?@FlashFan没有本机.bind
支持是很难做到的。或者,您可以开始将其构建到原型链中,但这只会将原型链弄得一团糟。不过,请参见编辑后的问题。重要提示:使用什么数组并不重要,只要它只包含一个元素。例如,var params=['cats'].concat(args)代码>也同样有效。原因是new
忽略了提供给bind的this
值。重要提示:数组的第一个元素是什么并不重要。例如,new(A.bind.apply(A,['cats',1,2]))()代码>也同样有效。原因是new
忽略了为绑定提供的this
值。使用提供的速记版本,您不需要最后两个括号“()”。因此它可以是:var a=new(a.bind.apply(a[null].concat([1,2])代码>最佳解决方案-我调整了您的解决方案,使其不必传递数组,而是像正常情况一样使用包装构造函数,例如新的包装构造函数(1,2,3)
。我还将构造函数添加到原型中,以获得良好的度量-分叉JSFIDLE:不幸的是,似乎没有办法保留返回类型的原始构造函数,这对构造函数的obj实例是有害的。ES5 FTW。
// 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]);