将所有参数传递给构造函数

时间:2012-05-12 13:37:28

标签: javascript constructor

基本上,我有一个像这样的构造函数:

function A() {
    this.content = toArray(arguments); // toArray converts it to an array
}

我想从另一个函数中调用它:

function B() {
    return new A();
}

问题是,我想将传递给B的所有参数传递给A

我无法使用apply(以常用方式):

  • 如果我只是apply任何旧对象
  • ,它将不是构造函数
  • 我不能applyprototype,除非有一种简单的方法来克隆它我不知道
  • 我不能再创建new A再次传递给它;实际上,如果没有传递任何参数,A()会抛出,我想保留此功能。

我想出了一些解决方案:

  • 另一个构造函数!

    function C() {}
    C.prototype = A.prototype;
    
    function B() {
        var obj = new C();
        A.apply(obj, arguments);
        return obj;
    }
    
  • 另一个功能!

    function _A(_arguments) {
        if(_arguments.length === 0) {
            return this;
        }
    
        // Do initialization here!
    }
    
    _A.prototype.constructor = A;
    
    function A() {
        if(arguments.length === 0) {
            throw new Error("That's not good.");
        }
    
        return new _A(toArray(arguments));
    }
    
    function B() {
        return new _A(toArray(arguments));
    }
    
  • 其余的格式几乎相同

但有没有一种非常简单明了的方法呢?

2 个答案:

答案 0 :(得分:7)

在ES5实现中,您可以使用Object.create创建从A.prototype继承的对象,然后将.apply()生成的对象创建到构造函数。

function A() {
    this.content = toArray(arguments); // toArray converts it to an array
}

function B() {
    var obj = Object.create(A.prototype);
    A.apply(obj, arguments);
    return obj;
}

然后你可以为不支持的实现提供Object.create

if (!Object.create)
    Object.create = function(proto) {
        function f() {}
        f.prototype = proto;
        return new f;
    }

当然它不是一个完整的垫片,但它足以满足您的需求。


或者您可以创建一个有效地为您完成所有功能的功能。

function apply_constructor(constr, args) {
    var obj = Object.create(constr.prototype);
    constr.apply(obj, args);
    return obj;
}

并像这样使用它:

function B() {
    return apply_constructor(A, arguments);
}

答案 1 :(得分:2)

在ES5中,您可以使用bind。

function B() {
  var args = Array.prototype.slice.call(arguments);
  var curriedCtor = Function.prototype.bind
      .apply(A, [null].concat(args));
  return new curriedCtor();
}

所以

function A(x, y) {
  this.x = x;
  this.y = y;
}

var test = B(1, 2);

alert(JSON.stringify(test));  // alerts {"x":1,"y":2}