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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5054926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 15:47:52  来源:igfitidea点击:

Javascript - Create instance with array of arguments

javascript

提问by Van Coding

I know the possibility to call a function with an array of arguments with apply(obj,args); Is there a way to use this feature when creating a new instance of a function?

我知道可以使用 apply(obj,args); 调用带有参数数组的函数;在创建函数的新实例时,有没有办法使用此功能?

I mean something like this:

我的意思是这样的:

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

I hope you understand what i mean... ^^^

我希望你明白我的意思...^^^

Thanks for your help!

谢谢你的帮助!

Solved!

解决了!

I got the right answer. To make the answer fit to my question:

我得到了正确的答案。为了使答案适合我的问题:

function A(arg1,arg2) {
    var a = arg1;
    var b = arg2;
}

var a = new (A.bind.apply(A,[A,1,2]))();

采纳答案by Raynos

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

We take a function and arguments and create a function that applies the arguments to that function with the this scope.

我们接受一个函数和参数并创建一个函数,该函数将参数应用于具有 this 作用域的该函数。

Then if you call it with the new keyword it passes in a new fresh thisand returns it.

然后,如果您使用 new 关键字调用它,它会传入一个新的新鲜事物this并返回它。

The important thing is the brackets

重要的是括号

new (wrapper(Constructor, [1,2]))

new (wrapper(Constructor, [1,2]))

Calls the new keyword on the function returned from the wrapper, where as

在从包装器返回的函数上调用 new 关键字,其中

new wrapper(Constructor, [1,2])

new wrapper(Constructor, [1,2])

Calls the new keyword on the wrapper function.

在包装函数上调用 new 关键字。

The reason it needs to be wrapped is so that thisthat you apply it to is set with the new keyword. A new thisobject needs to be created and passed into a function which means that you must call .apply(this, array)inside a function.

它需要被包装的原因是this你应用它是用 new 关键字设置的。this需要创建一个新对象并将其传递给函数,这意味着您必须.apply(this, array)在函数内部调用。

Live example

活生生的例子

Alternatively you could use ES5 .bindmethod

或者你可以使用 ES5.bind方法

var wrapper = function(f, args) {
    var params = [f].concat(args);
    return f.bind.apply(f, params);
};

See example

查看示例

回答by sqykly

with ECMAscript 5 you can:

使用 ECMAscript 5,您可以:

function createInstanceWithArguments (fConstructor, aArgs) {
    var foo = Object.create(fConstructor.prototype);
    fConstructor.apply(foo, aArgs);
    return foo;
}

回答by Jon Jaques

@Raynos answer works well, except that the non-ES5 version is missing the constructor's prototype after instantiation.

@Raynos 答案效果很好,只是非 ES5 版本在实例化后缺少构造函数的原型。

Here's my updated cApplymethod:

这是我更新的cApply方法:

var cApply = function(c) {
  var ctor = function(args) {
    c.apply(this, args);
  };
  ctor.prototype = c.prototype;
  return ctor;
};

Which can be used like this:

可以这样使用:

var WrappedConstructor = cApply(Constructor);
var obj = new WrappedConstructor([1,2,3]);

// or inline like this.    
var obj2 = new (cApply(Constructor))([1,2,3]);

JSFiddlefor reference.

JSFiddle供参考。

回答by inf3rno

You can use Object.create()to build the new instance, and call the constructor on the instance after that:

您可以使用Object.create()来构建新实例,然后在实例上调用构造函数:

var args = [1,2,3];
var instance = Object.create(MyClass.prototype);
MyClass.apply(instance, args);

or in a single line:

或在一行中:

var instance = MyClass.apply(Object.create(MyClass.prototype), args);

but don't forget return this;in MyClassby this single line solution.

但不要忘记return this;MyClass这个单一的在线解决方案。

If you don't have Object.create(), then it is very simple to write one:

如果你没有Object.create(),那么写一个很简单:

Object.create = function (source){
    var Surrogate = function (){};
    Surrogate.prototype = source;
    return new Surrogate();
};

You can optionally write an Function.newInstance()or a Function.prototype.newInstance()function:

您可以选择编写一个Function.newInstance()或一个Function.prototype.newInstance()函数:

Function.newInstance = function (fn, args){
    var instance = Object.create(fn.prototype);
    fn.apply(instance, args);
    return instance;
};

so var instance = Function.newInstance(MyClass, args);.

所以var instance = Function.newInstance(MyClass, args);

note: It is not recommended to override native classes.

注意:不建议覆盖本机类。

回答by sdleihssirhc

You can curry the functions:

你可以咖喱函数:

function A(arg1, arg2) {
    // ...
}

function A12() {
    A(1, 2);
}

You could even build a curry factory:

你甚至可以建造一个咖喱工厂:

function A_curry() {
    var args = arguments;
    return function () {
        A.apply(null, args);
    };
}

回答by Wilt

What if you have your object class name stored in a variable called className?

如果您将对象类名存储在名为 的变量中会className怎样?

var className = 'A'

According to this answer hereit all becomes very clean and simple using ECMAScipt5's Function.prototype.bindmethod.

根据这里的答案,使用ECMAScipt5Function.prototype.bind方法,一切都变得非常干净和简单。

With an array of arguments:

使用一系列参数:

new ( Function.prototype.bind.apply( className, arguments ) );

Or with an argument list:

或者使用参数列表:

new ( Function.prototype.bind.call( className, argument1, argument2, ... ) );

A single line, no need for a wrapper.

单行,不需要包装器。

回答by Toufiqur Chowdhury

I just had the same issue and also wanted to preserve prototype properties of the target object. After looking at the answers, just came up with a rather simple solution. Thought I might as well share it for any future seeker :)

我只是遇到了同样的问题,并且还想保留目标对象的原型属性。查看答案后,只是想出了一个相当简单的解决方案。我想我不妨为任何未来的寻求者分享它:)

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