2012-03-09 13 views
9

मैं इस पोस्ट में आया था http://www.webmasterworld.com/javascript/3066162.htm जावास्क्रिप्ट में कैसे जब आप किसी ऑब्जेक्ट को तत्काल परिभाषित करते हैं तो इसमें अक्षर परिभाषित होते हैं, तो प्रत्येक बार जब कोई तत्काल होता है तो इसकी विधियों की प्रतिलिपि बनाई जाती है। इसलिए यदि आपके पास ऑब्जेक्ट के उदाहरणों का एक समूह है तो प्रतिलिपि बनाई गई विधियों को स्मृति में जोड़ना शुरू हो जाएगा।ऑब्जेक्ट शाब्दिक नोटेशन बनाम प्रोटोटाइप गति और मेमोरी

वह कैसे कहता है कि आपकी विधियों को बनाने के लिए प्रोटोटाइप का उपयोग करना अधिक कुशल है क्योंकि कन्स्ट्रक्टर ऑब्जेक्ट के प्रत्येक उदाहरण के लिए विधियों की प्रतिलिपि नहीं बनाई जाती है।

यह सच है? क्योंकि मैं इस धारणा के तहत था कि प्रोटोटाइप ने ऑब्जेक्ट के बजाए ऑब्जेक्ट को तत्काल बनाया जाने के बाद भी गुण/विधियों को जोड़ने की अनुमति दी थी।

+2

मैं सिर्फ यह ध्यान रखना चाहता हूं कि कन्स्ट्रक्टर के भीतर से एक विधि बनाने से वास्तव में स्मृति में पूरी विधि की एक नई प्रतिलिपि नहीं बनती है - एक नया संदर्भ बस मौजूदा विधि में बनाया जाता है।हालांकि, प्रोटोटाइप अभी भी तेज होते हैं क्योंकि यह सब जावास्क्रिप्ट इंजन द्वारा संभाला जाता है, और इसलिए यह रास्ते पर बहुत से अनुकूलन कर सकता है, जो हजारों ऑब्जेक्ट्स को तुरंत चालू करते समय जल्दी से ध्यान देने योग्य हो जाता है। Google ने V8 में प्रोटोटाइप श्रृंखला के बाहर बकवास को अनुकूलित किया, जो आंशिक रूप से यह बहुत तेज़ क्यों है। –

+0

@musicfreak जो जानने के लिए अलग-अलग है, धन्यवाद आदमी। – zero

उत्तर

10

यह सच है, यही कारण है कि prototype है।

// define Function foo 
function Foo() 
{ 
    this.x = 1; 
    this.bar = 'bar'; 
} 

// define method on Foo's prototype 
Foo.prototype.helloBar = function() 
{ 
    alert(this.bar); 
} 


var foobar = new Foo(); 

foobar.helloBar(); // alerts "bar" 

Foo.prototype का उपयोग करते हुए प्रत्येक उदाहरण new Foo() के लिए hellobar को पुनर्परिभाषित करने के साथ जुड़े अनावश्यक अतिरिक्त बिट्स से बचाता है।

+0

मुझे लगता है कि मैं उलझन में हूँ। प्रोटोटाइप कुछ ऐसा है जो वस्तु के प्रत्येक उदाहरण के संदर्भ में है (जैसे फ़ंक्शन को कॉल करना) – zero

+3

@ कोडोडम्बैट: यह सही है। 'प्रोटोटाइप 'ऑब्जेक्ट को उसी कन्स्ट्रक्टर फ़ंक्शन से बनाए गए सभी ऑब्जेक्ट्स के बीच साझा किया जाता है। वे उन गुणों तक पहुंचने के लिए * संदर्भित करते हैं जिनके पास स्वयं नहीं हैं। –

+0

इस मामले में, *** फंक्शन फू की सभी वस्तुओं ***। – xandercoded

14

जब आप इस तरह एक वस्तु बनाने के लिए:

function Car(c) { 
    this.color = c; 
    this.drive = function() {}; 
} 

आप वास्तव में एक कार आपके द्वारा बनाए गए के लिए ड्राइव समारोह की एक प्रति बना रहे हैं। जावास्क्रिप्ट में, प्रत्येक ऑब्जेक्ट में प्रोटोटाइप पॉइंटर और गुण/विधियां होती हैं जो उस प्रोटोटाइप से पेड़ को बाल वस्तुओं तक फैलती हैं।

जब आप ऐसा करेंगे:

function Car(c) {this.color=c}; 
Car.prototype.drive = function {}; 

और फिर कुछ ही कार बनाने वस्तुओं आप इस बजाय साथ अंत:

 
      {drive: function(){}} 
      /  |   \ 
     car1 (red) car2 (blue) car3 (green) 

drive समारोह सभी कार वस्तुओं के बीच साझा किया जाता है। यह एक शर्म की बात है कि जावास्क्रिप्ट में ऐसा करने के लिए वाक्यविन्यास इतना अजीब है।

+0

⇈ यह अच्छा जवाब है। – Daniel

1

कन्स्ट्रक्टर फ़ंक्शन के प्रोटोटाइप पर परिभाषित विधियां समान अन्य भाषाओं में कक्षा परिभाषा के लिए है। जावा क्लास में परिभाषित विधियों, उदाहरण के लिए, उस वर्ग के सभी उदाहरणों द्वारा साझा की जाती हैं। जावास्क्रिप्ट में, कन्स्ट्रक्टर फ़ंक्शन के प्रोटोटाइप पर परिभाषित विधियों को उस कन्स्ट्रक्टर फ़ंक्शन से बनाए गए सभी उदाहरणों द्वारा साझा किया जाता है।

उपर्युक्त उदाहरण में मुख्य अंतर परिवर्तनीय घोषणाएं है। एक प्रोटोटाइप पर परिभाषित एक चर को उन उदाहरणों के बीच साझा किया जाएगा जहां कक्षा के प्रत्येक उदाहरण में कक्षा परिभाषा में चर की अपनी प्रति होगी।

कुछ प्रयोग के माध्यम से समझने का सबसे आसान तरीका होगा। http://jsfiddle.net/3vn4A/

फ़ायरफ़ॉक्स ऑब्जेक्ट में __proto__ पॉइंटर के माध्यम से सीधे उनके प्रोटोटाइप तक पहुंच सकते हैं। Object.getPrototypeOf(obj) ऑब्जेक्ट के प्रोग्रामेटिक रूप से इसके प्रोटोटाइप को संदर्भित करने का मानक तरीका है।

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