9

मैं एक्मास्क्रिप्ट 5 spec में ऑब्जेक्ट.क्रेट के साथ खेल रहा हूं, और मैं एकाधिक विरासत प्रकार की संरचना बनाने की कोशिश कर रहा हूं।ऑब्जेक्ट.क्रेट बनाम प्रत्यक्ष प्रोटोटाइपल विरासत

कहें कि मेरे पास कुछ कार्य हैं: ए, बी, और सी। केवल प्रोटोटाइप के साथ काम कर के साथ, मैं यह कर सकता हूँ:

function a() {} 
a.prototype = { 
    fnA = function() {}, 
    propA = 500 
}; 

var b = Object.create(new a()); 
b.fnB = function() {}; 
b.propB = 300; 

var c = Object.create(b); 
c.fnC = function() {}; 
c.propC = 200; 

मुझे लगता है कि मैं एक ही परिणाम दोनों तरीकों से मिलती है:

function a() {} 
a.prototype = { 
    fnA = function() {}, 
    propA = 500 
}; 

function b() {} 
b.prototype = a.prototype; 
b.prototype.fnB = function() {}; 
b.prototype.propB = 300; 

function c() {} 
c.prototype = b.prototype; 
c.prototype.fnC = function() {}; 
c.prototype.propC = 200; 

लेकिन Object.create का उपयोग कर, मैं कुछ ऐसा कर होगा।

यह थोड़े घबराहट लगता है, क्योंकि मैं एक कन्स्ट्रक्टर फ़ंक्शन के बजाय ऑब्जेक्ट पर वापस आ जाता हूं। ऐसा लगता है कि नियमित प्रोटोटाइपल विरासत करना कम घुसपैठ कर रहा है और मॉड्यूलर अनुप्रयोगों के लिए अधिक समझ में आता है जिन्हें काम करने के लिए किसी विशेष उपचार की आवश्यकता नहीं होती है।

क्या मुझे कुछ याद आ रही है? क्या रचनाकार बनाने के साथ Object.create बनाने की कोशिश करने का कोई फायदा है? या यह मौजूदा वस्तुओं की प्रतिलिपि बनाने के लिए केवल उपयोगी है? मैं प्रोटोटाइप से जुड़े कार्यों & कार्यों तक पहुंच चाहता हूं, और ऑब्जेक्ट में बाद में जोड़े गए कार्यों और गुणों को नहीं।

या इसके बारे में क्या (या बेहतर गहरी प्रतिलिपि का उपयोग करें, लेकिन विचार वही रहता है)?

function A() {} 
A.prototype = { 
    fn: function() { 
     console.log(this.propA + 30); 
    }, 
    propA: 20 
}; 

function B() {} 
Object.keys(A.prototype).forEach(function (item) { 
    B.prototype[item] = A.prototype[item]; 
}); 
B.prototype.propA = 40; 

function C() {} 
Object.keys(B.prototype).forEach(function (item) { 
    C.prototype[item] = B.prototype[item]; 
}); 
C.prototype.fn = function() { 
    console.log(this.propA + 3); 
}; 


var a = new A(), 
    b = new B(), 
    c = new C(); 

a.fn(); 
b.fn(); 
c.fn(); 

उत्तर

4

वास्तव में आपको दोनों तरीकों से एक ही परिणाम नहीं मिलता है।

b.prototype = a.prototype; 

यह क्या कर रही है a.prototype के रूप में बिल्कुल एक ही वस्तु संदर्भ के लिए b.prototype स्थापित कर रही है: इस लाइन पर विचार करें। यदि आप पहली वस्तु को बदलते हैं (fnB विधि जोड़कर कहें) तो आप दूसरी ऑब्जेक्ट को भी बदल देंगे। वे एक जैसी ही चीज हैं। कोड के पहले सेट के अंत में आपके पास तीन प्रोटोटाइप होंगे जो सभी समान तरीके और गुणों के साथ बिल्कुल समान हैं।

प्रोटोटाइप विरासत का पूरा बिंदु यह है कि आप एक "रोचक" वस्तु (यानी, अपने इच्छित व्यवहार के साथ) को परिभाषित करते हैं और उसके बाद इसे ऑब्जेक्ट.क्रेट के साथ क्लोन करें और क्लोन को अपनी आवश्यकताओं के अनुसार संशोधित करें (आमतौर पर संशोधित करके इसकी गुण, इसकी विधियां नहीं)।

तो मान लें कि आपने एक योजक वस्तु है:

var adder = {x: 0, y: 0}; 
adder.execute = function() { 
    return this.x + this.y; 
} 

तो फिर तुम एक क्लोन बना सकते हैं और उसके गुण सेट करें:

var myadder = Object.create(adder); 
myadder.x = 1; 
myadder.y = 2; 
console.log(myadder.execute()); // 3 

अब स्पष्ट रूप से यह एक मूर्खतापूर्ण उदाहरण है, लेकिन शो है कि आप कर सकते हैं उन रचनाकारों पर रचनाकारों और स्पष्ट प्रोटोटाइप लिखने के बिना प्रोटोटाइप विरासत के बारे में सोचें।

+0

ठीक है, मैं ऐसा लगता। लेकिन क्या होगा यदि मैंने सभी गुणों को ए से बी के प्रोटोटाइप में कॉपी किया, तो प्रोटोटाइप में सामान जोड़ा, फिर सी के लिए ऐसा ही किया? क्या यह वही चीज़ प्राप्त करेगा? – tjameson

+2

'ऑब्जेक्ट.क्रेट' का उपयोग करने के लिए बेहतर। तो, 'बी.प्रोटोटाइप = ऑब्जेक्ट.क्रेट (ए.प्रोटोटाइप);' और फिर हम बेहतर समाधान का उपयोग कर कम समाधान को बेहतर बनाते हैं। – jmbucknall

+0

क्या मैं एक और निर्माता बना सकता हूं? मान लें कि मैं Object.create करता हूं, क्या मैं 'नया कार्य कर सकता हूं) (} {} new.prototype = Object.create (बी);' या कुछ समान है? मैं बस एक निर्यात योग्य समारोह चाहता हूँ ... – tjameson

0

आप ब्राउज़रों कि समर्थन नहीं करते Object.create() आप इस

function object(o) { 
    function F() {} 
    F.prototype = o; 
    return new F(); 
} 

वस्तु समारोह का उपयोग कर सकते समर्थन करने के लिए की जरूरत है जावास्क्रिप्ट के निर्माता पैटर्न untangles, सच मूलरूप विरासत को प्राप्त करने। यह एक पुरानी वस्तु को पैरामीटर के रूप में लेता है और एक खाली नई वस्तु देता है जो पुराने से प्राप्त होता है। यदि हम किसी नए ऑब्जेक्ट से सदस्य प्राप्त करने का प्रयास करते हैं, और इसमें उस कुंजी की कमी है, तो पुरानी वस्तु सदस्य की आपूर्ति करेगी।वस्तुओं वस्तुओं से प्राप्त होता है। उस से अधिक ऑब्जेक्ट उन्मुख क्या हो सकता है?

अधिक यहाँ पढ़ा जा सकता: Prototypal Inheritance in JavaScript

+0

पर वापस नहीं ले जाते हैं क्योंकि ऑब्जेक्ट.क्रेट एक दूसरा पैरामीटर लेता है जिसे आप पॉली भर नहीं सकते हैं, आप एक त्रुटि फेंकना चाहते हैं अगर कोई इसे प्रदान करता है। बस आप या आपके कोड का उपयोग करने वाले किसी अन्य व्यक्ति के पास अप्रत्याशित व्यवहार की बजाय स्पष्ट त्रुटि होगी: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Cross-browser_compatibility – HMR

संबंधित मुद्दे