2012-05-12 244 views
6

基本上,我有一個構造函數是這樣的:將所有參數傳遞給構造

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)); 
    } 
    
  • 他們的其餘部分是幾乎同樣的事情在不同的格式

但有一個非常簡單而明顯的方式做到這一點?

回答

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); 
} 
+0

'Object.create'是完美的。謝謝! – Ryan

+0

@minitech:不客氣。 –

2

在ES5,可以使用綁定。

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}