ES6类中的constr.apply(this,args)

我已经使用下面的函数来创build一些未知类的实例:

Kernel.prototype._construct = function (constr, args) { function F() { constr.apply(this, args); // EXCEPTION! } F.prototype = constr.prototype; return new F(); }; 

如果我使用原型,一切正常:

 function Person(name, surname) { this.name = name; this.surname = surname; } var person = Kernel._construct(Person, ["name", "surname"]); // WORKS! 

但是,有些人正在使用节点v4 +中使用ES6本机类的库:

 class Person { constructor(name, surname) { this.name = name; this.surname = surname; } } var person = Kernel._construct(Person, ["name", surname]); // EXCEPTION! 

他们得到一个错误:

 TypeError: Class constructors cannot be invoked without 'new' 

我需要能够调用具有未知数量的参数的构造函数。 有关如何解决这个问题的任何想法?

有多种方法可以做到这一点:

  1. 使用Function对象的方法:

     Kernel.prototype._construct = function (constr, args) { return new (Function.prototype.bind.apply(constr, [null].concat(args))); }; 

    这里我们将 args作为bind参数。 目标是有一个函数,可以调用没有arugments,所以我们可以调用new x()bind为我们做这个,但我们需要正确地设置它。 语法是:

     func.bind(thisArg[, arg1][, args2...]) // calling the results from the above is like // thisArg.func(arg1, arg2...); 

    我们要使用constr作为绑定的函数,而args的项作为参数。 我们不关心这个thisArg 。 为此,我们需要将args数组“转换”为参数。 apply电话确实如此:

     func.apply(thisArg[, args]); // calling the results from the above is like // thisArg.func(args[0], args[1]...); 

    apply实际上是调用bind 。 第一项[null]非常重要,因为我们想调用bind ,其中thisArgnull – 像这样: constr.bind(null, args[0], args[1]...)

  2. 使用ES2015 Spread操作符 :

     Kernel.prototype._construct = function (constr, args) { return new constr(...args); }; 

    这简单得多,但是有两个问题:

    1. 它需要ES2015支持,甚至最新的Node(v4.2.1)也需要一个标志( –harmony_spreadcalls )。
    2. 这将产生一个语法错误,如果不支持,甚至不能有条件地执行,否则使用dynamic脚本( eval() / new Function(...) ) – 这是不build议的。
  3. 使用Reflect内置的对象。

     Kernel.prototype._construct = function (constr, args) { return Reflect.construct(constr, args); }; 

    这也很简单,但在支持方面更为落后(基本上你必须使用babel)。

你可以通过将参数绑定到函数然后调用new来解决这个问题:

 Kernel.prototype._construct = function (constr, args) { var F = constr.bind(null, args); return new F(); }; 

好的问题,但不是 ,根据ECMAScript§9.22,不能在ES6中调用没有new关键字的构造函数 。

我在这里问了一个相同的问题: ES6:没有新关键字的调用类构造函数

我需要能够调用具有未知数量的参数的构造函数。 任何想法如何解决这个问题?

那么这不说(不)使用new关键字,但你可以很容易地在ES6构造函数中使用可变参数

 class Person { constructor(name, surname, ...others) { this.name = name; this.surname = surname; this.others = others || []; } } let p = new Person('OweR', 'ReLoaDeD', 'a', 'b', 'c'); p; //=> {"name":"OweR","surname":"ReLoaDeD","others":["a","b","c"]} 

我怀疑这不是你想要的。 但是,如果您尝试避免使用new来调用ES6中的类,则无法完成。


所以,就这样说,你究竟在做什么?