Javascript-使用参数数组创建实例

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

我知道可以使用参数数组调用函数,参数为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(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关键字调用它,它将传入一个新的fresh
this
并返回它

重要的是括号

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]);