2012-05-12 21 views
6

मूल रूप से, मेरे पास है इस तरह एक निर्माता:एक निर्माता के सभी तर्क पासिंग

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

मैं इसे एक और समारोह से कॉल करने के लिए करना चाहते हैं:

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

समस्या नहीं, मैं होता है B पर A तक के सभी तर्कों को पारित करना पसंद है।

मैं apply उपयोग कर सकते हैं नहीं (एक आम रास्ते में):

  • यह एक निर्माता नहीं होगा अगर मैं सिर्फ apply यह किसी भी पुराने वस्तु को
  • मैं नहीं करने के लिए apply यह कर सकते हैं prototype, जब तक कि इसे क्लोन करने का कोई आसान तरीका न हो, मुझे
  • के बारे में पता नहीं है, मैं इसे फिर से पास करने के लिए 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} 
संबंधित मुद्दे