दिलचस्प पोस्ट
क्या पायथन में कई पंक्तियों में एक लंबी रेखा को तोड़ना संभव है ksoap2 – android का उपयोग कर साबुन हेडर कैसे सेट करें कोर डंप फ़ाइल विश्लेषण एक नई पंक्ति तक जब तक कंस को सफेद स्थान के साथ पढ़ा जाए? कैसे करें: कस्टम विजेट के लिए विषय (शैली) आइटम को परिभाषित करें एसवीजीएस IE में ठीक से स्केलिंग नहीं कर रहे हैं – अतिरिक्त जगह है जब पॉड इंस्टॉल चल रहा है तो मुझे `मास्टर` रेपो को कोकाओपॉड 0.32.1 की आवश्यकता है, अपडेट करने का प्रयास करें, लेकिन अभी भी 0.31 में क्या मैं डिस्पोज़ () डाटासेट और डाटाटेबल? एक सूची से SqlBulkCopy <> कोड मेट्रिक्स के साथ क्या आकर्षण है? MySQL और जेडीबीसी के साथ दोबारा लिखे गए स्टैटमेंट्स = सच कैसे 2d सरणी के लिए एक 1d सरणी कन्वर्ट करने के लिए? वैराइडीक ने योग समारोह को क्युरीज किया मैं नेट पर 7-ज़िप अभिलेखागार कैसे बना सकता हूं? फ़ॉर्म के बीच डेटा कैसे साझा करें?

'प्रोटोटाइप बनाम' का प्रयोग जावास्क्रिप्ट में 'यह'

के बीच क्या अंतर है

var A = function () { this.x = function () { //do something }; }; 

तथा

 var A = function () { }; A.prototype.x = function () { //do something }; 

Solutions Collecting From Web of "'प्रोटोटाइप बनाम' का प्रयोग जावास्क्रिप्ट में 'यह'"

उदाहरणों में बहुत अलग परिणाम हैं

मतभेदों को देखकर, निम्नलिखित नोट किया जाना चाहिए:

  • एक निर्माता का प्रोटोटाइप उदाहरण के निजी [[Prototype]] संपत्ति के माध्यम से उदाहरणों में तरीकों और मूल्यों को साझा करने का एक तरीका प्रदान करता है।
  • फ़ंक्शन का यह सेट है कि कैसे फ़ंक्शन को बुलाया जाता है या बाइंड के इस्तेमाल से (यहाँ पर चर्चा नहीं की गई है)। जहां किसी ऑब्जेक्ट (जैसे myObj.method() ) पर एक फ़ंक्शन बुलाया जाता है, तब यह विधि के भीतर ऑब्जेक्ट का संदर्भ देता है। जहां यह कॉल द्वारा या बाइंड के उपयोग से सेट नहीं किया जाता है, यह वैश्विक ऑब्जेक्ट (ब्राउज़र में विंडो) या सख्त मोड में डिफ़ॉल्ट होता है, अनिर्धारित रहता है।
  • जावास्क्रिप्ट एक ऑब्जेक्ट ओरिएंटेड भाषा है, अर्थात् सब कुछ एक ऑब्जेक्ट है, जिसमें फ़ंक्शन शामिल हैं।

तो सवाल में स्निपेट्स यहां हैं:

 var A = function () { this.x = function () { //do something }; }; 

इस मामले में, वेरिएबल A को असाइन किया जाता है जो फ़ंक्शन के संदर्भ में होता है। जब उस फ़ंक्शन को A() का उपयोग किया जाता है, तो फ़ंक्शन का कॉल कॉल द्वारा सेट नहीं होता है, इसलिए यह वैश्विक ऑब्जेक्ट के लिए डिफ़ॉल्ट होता है और अभिव्यक्ति यह window.x प्रभावी रूप से window.x परिणाम यह है कि दाएं हाथ की ओर फ़ंक्शन अभिव्यक्ति का एक संदर्भ window.x को असाइन किया गया है।

के मामले में:

 var A = function () { }; A.prototype.x = function () { //do something }; 

कुछ बहुत अलग होता है। पहली पंक्ति में, चर A को फ़ंक्शन के संदर्भ निर्दिष्ट किया जाता है। जावास्क्रिप्ट में, सभी फ़ंक्शंस ऑब्जेक्ट्स की एक प्रोटोटाइप प्रॉपर्टी डिफ़ॉल्ट रूप से होती है, इसलिए कोई एप्रोटोटाइप ऑब्जेक्ट बनाने के लिए कोई अलग कोड नहीं है।

दूसरी पंक्ति में, A.prototype.x को फ़ंक्शन के संदर्भ निर्दिष्ट किया जाता है। यह एक्स संपत्ति बना देगा यदि वह मौजूद नहीं है, या यदि ऐसा होता है तो नया मान असाइन करें तो पहले उदाहरण के साथ अंतर यह है कि अभिव्यक्ति में ऑब्जेक्ट की एक्स प्रॉपर्टी शामिल है।

एक और उदाहरण नीचे है यह पहले के जैसा है (और हो सकता है कि आप किस बारे में पूछना चाहते हैं):

 var A = new function () { this.x = function () { //do something }; }; 

इस उदाहरण में, new ऑपरेटर फ़ंक्शन अभिव्यक्ति से पहले जोड़ा गया है ताकि फ़ंक्शन को कन्स्ट्रक्टर के रूप में कहा जाता है। जब new साथ फोन किया जाता है, फ़ंक्शन यह एक नई ऑब्जेक्ट को संदर्भित करता है जिसका निजी [[Prototype]] प्रॉपर्टी को कंसट्रक्टर के सार्वजनिक प्रोटोटाइप के संदर्भ में सेट किया जाता है। इसलिए असाइनमेंट कथन में, x प्रॉपर्टी इस नए ऑब्जेक्ट पर बनाई जाएगी। जब एक कन्स्ट्रक्टर के रूप में कहा जाता है, तो फ़ंक्शन डिफ़ॉल्ट रूप से इस ऑब्जेक्ट को देता है, इसलिए return this; अलग return this; की कोई आवश्यकता नहीं है return this; बयान।

यह जांचने के लिए कि में एक्स संपत्ति है:

 console.log(Ax) // function () { // //do something // }; 

यह नये का एक असामान्य उपयोग है, क्योंकि कंसट्रक्टर को संदर्भित करने का एकमात्र तरीका ए कंसट्रक्टर के माध्यम से है। यह करने के लिए अधिक सामान्य होगा:

 var A = function () { this.x = function () { //do something }; }; var a = new A(); 

समान परिणाम प्राप्त करने का एक अन्य तरीका एक तत्काल लागू कार्य अभिव्यक्ति का उपयोग करना है:

 var A = (function () { this.x = function () { //do something }; }()); 

इस स्थिति में, A को दाहिने हाथ की ओर फ़ंक्शन बुलाए जाने के रिटर्न वैल्यू को असाइन किया गया। यहां फिर से, क्योंकि यह कॉल में सेट नहीं है, यह वैश्विक ऑब्जेक्ट का संदर्भ देगा और यह window.x प्रभावी रूप से window.x । चूंकि फ़ंक्शन कुछ भी वापस नहीं करता है, A को undefined एक मूल्य होगा।

दो तरीकों के बीच ये मतभेद भी प्रकट होते हैं कि आप अपने जावास्क्रिप्ट ऑब्जेक्ट्स को / से JSON से serializing और डे-धारावाहिक कर रहे हैं। ऑब्जेक्ट के प्रोटोटाइप पर परिभाषित विधियों को क्रमबद्ध नहीं किया जाता है, जब आप ऑब्जेक्ट को सीरियल कर सकते हैं, जो सुविधाजनक हो सकता है, उदाहरण के लिए, आप किसी ऑब्जेक्ट के केवल डेटा भाग को सीरियल करना चाहते हैं, लेकिन इसके तरीके नहीं हैं:

 var A = function () { this.objectsOwnProperties = "are serialized"; }; A.prototype.prototypeProperties = "are NOT serialized"; var instance = new A(); console.log(instance.prototypeProperties); // "are NOT serialized" console.log(JSON.stringify(instance)); // {"objectsOwnProperties":"are serialized"} 

संबंधित प्रश्न :

  • इसका अर्थ क्या है कि जावास्क्रिप्ट एक प्रोटोटाइप भाषा है?
  • जावास्क्रिप्ट में फ़ंक्शन का दायरा क्या है?
  • "यह" कीवर्ड कैसे काम करता है?

सिडेनोट: दो तरीकों के बीच कोई महत्वपूर्ण मेमोरी बचत नहीं हो सकती है, हालांकि तरीकों को साझा करने के लिए प्रोटोटाइप का उपयोग करना और गुणों की संभावना प्रत्येक मेमोरी की अपनी कॉपी होने से कम मेमोरी का उपयोग करेगी।

जावास्क्रिप्ट एक निम्न स्तरीय भाषा नहीं है। प्रोटोटाइप या अन्य विरासत पद्धतियों के बारे में सोचना बहुत मूल्यवान नहीं हो सकता है, जिस तरह से स्मृति को आवंटित करने के तरीके को स्पष्ट रूप से बदलना है।

जैसा कि दूसरों ने पहले संस्करण को कहा है, "ए" का कार्य पद्धति "स्वतंत्र" की अपनी स्वतंत्र प्रति की क्लास ए के हर उदाहरण में "यह" परिणाम का उपयोग करते हुए। जबकि "प्रोटोटाइप" का उपयोग करने का यह मतलब होगा कि वर्ग ए के प्रत्येक उदाहरण "x" विधि की एक ही प्रति का उपयोग करेंगे।

इस सूक्ष्म अंतर को दिखाने के लिए कुछ कोड दिया गया है:

 // x is a method assigned to the object using "this" var A = function () { this.x = function () { alert('A'); }; }; A.prototype.updateX = function( value ) { this.x = function() { alert( value ); } }; var a1 = new A(); var a2 = new A(); a1.x(); // Displays 'A' a2.x(); // Also displays 'A' a1.updateX('Z'); a1.x(); // Displays 'Z' a2.x(); // Still displays 'A' // Here x is a method assigned to the object using "prototype" var B = function () { }; B.prototype.x = function () { alert('B'); }; B.prototype.updateX = function( value ) { B.prototype.x = function() { alert( value ); } } var b1 = new B(); var b2 = new B(); b1.x(); // Displays 'B' b2.x(); // Also displays 'B' b1.updateX('Y'); b1.x(); // Displays 'Y' b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances 

जैसा कि अन्य लोगों ने उल्लेख किया है, एक विधि या दूसरे को चुनने के कई कारण हैं मेरा नमूना सिर्फ स्पष्ट रूप से अंतर का प्रदर्शन करना है

इन 2 उदाहरणों को लें:

 var A = function() { this.hey = function() { alert('from A') } }; 

बनाम

 var A = function() {} A.prototype.hey = function() { alert('from prototype') }; 

ज्यादातर लोग यहां (विशेषकर शीर्ष-रेट किए गए उत्तरों) इस बात की व्याख्या करने की कोशिश करते हैं कि वे किस प्रकार बताए बिना क्यों अलग हैं। मुझे लगता है कि यह गलत है और यदि आप पहले बुनियादी बातों को समझते हैं, तो अंतर स्पष्ट हो जाएगा पहले बुनियादी बातों को समझाने की कोशिश करते हैं …

ए) एक समारोह जावास्क्रिप्ट में एक वस्तु है जावास्क्रिप्ट में हर वस्तु एक आंतरिक संपत्ति (अर्थात्, आप इसे अन्य गुणों की तरह एक्सेस नहीं कर सकते हैं, शायद क्रोम जैसे ब्राउज़रों में), जिसे अक्सर __proto__ रूप में संदर्भित किया जाता है (आप वास्तव में क्रोम में anyObject.__proto__ को टाइप कर सकते हैं यह देखने के लिए कि यह संदर्भ क्या है। यह सिर्फ यही है, एक संपत्ति, कुछ और नहीं। जावास्क्रिप्ट में एक संपत्ति = वस्तु के अंदर एक चर, और कुछ नहीं। वेरिएबल क्या करते हैं? वे चीजों को इंगित करते हैं।

तो यह __proto__ संपत्ति का क्या गुण है? ठीक है, आमतौर पर एक और वस्तु (हम बाद में क्यों समझाएँगे) __proto__ संपत्ति के लिए जावास्क्रिप्ट को एक अन्य वस्तु के लिए इंगित करने का एकमात्र तरीका है var newObj = Object.create(null) । यहां तक ​​कि अगर आप ऐसा करते हैं, __proto__ संपत्ति अभी भी ऑब्जेक्ट की संपत्ति के रूप में मौजूद है, बस किसी दूसरे ऑब्जेक्ट को इंगित नहीं करती है, यह null इंगित करता है।

यहां जहां ज्यादातर लोग उलझन में हैं:

जब आप जावास्क्रिप्ट में एक नया फ़ंक्शन बनाते हैं (जो एक ऑब्जेक्ट भी है, याद है?), पल यह परिभाषित किया गया है, जावास्क्रिप्ट स्वचालित रूप से prototype नामक उस फ़ंक्शन पर एक नई प्रॉपर्टी बनाता है। कोशिश करो:

 var A = []; A.prototype // undefined A = function() {} A.prototype // {} // got created when function() {} was defined 

A.prototype पूरी तरह से __proto__ प्रॉपर्टी से __proto__ है। हमारे उदाहरण में, 'ए' में अब दो प्रॉपर्टी 'प्रोटोटाइप' और __proto__ । यह लोगों के लिए एक बड़ा भ्रम है prototype और __proto__ गुण किसी भी तरह से संबंधित नहीं हैं, वे पृथक मूल्यों की ओर इशारा करते हुए अलग चीजें हैं।

आपको आश्चर्य हो सकता है: जावास्क्रिप्ट में __proto__ प्रॉपर्टी हर एक ऑब्जेक्ट पर क्यों बनाई जाती है? अच्छा, एक शब्द: प्रतिनिधिमंडल जब आप किसी ऑब्जेक्ट पर एक ऑब्जेक्ट कॉल करते हैं और ऑब्जेक्ट के पास नहीं है, तो जावास्क्रिप्ट __proto__ द्वारा संदर्भित ऑब्जेक्ट के लिए देखता है, यह देखने के लिए कि क्या इसमें शायद यह है। अगर यह नहीं है, तो यह उस ऑब्जेक्ट की __proto__ प्रॉपर्टी और इतने पर दिखता है … जब तक चेन समाप्त नहीं हो जाती। इस प्रकार नाम प्रोटोटाइप श्रृंखला बेशक, यदि __proto__ किसी ऑब्जेक्ट को इंगित नहीं करता है और न बदले, अच्छी तरह से कठिन भाग्य के लिए इंगित करता है, तो जावास्क्रिप्ट को यह पता चलता है कि आप संपत्ति के लिए undefined होंगे।

आप यह भी सोच सकते हैं, जब आप फ़ंक्शन परिभाषित करते हैं तो जावास्क्रिप्ट एक फ़ंक्शन के लिए prototype नामक एक संपत्ति क्यों बनाता है? क्योंकि यह आपको बेवकूफ बनाने की कोशिश करता है, हाँ आप को बेवकूफ़ बनाते हैं कि यह कक्षा-आधारित भाषाओं की तरह काम करता है

चलो हमारे उदाहरण के साथ चलते हैं और A से "ऑब्जेक्ट" बनाते हैं:

 var a1 = new A(); 

पृष्ठभूमि में कुछ हो रहा है जब यह हुआ था। a1 एक सामान्य परिवर्तनीय है जिसे एक नया, खाली ऑब्जेक्ट सौंपा गया था।

तथ्य यह है कि आपने फ़ंक्शन मंगलाए जाने से पहले ऑपरेटर का उपयोग किया था A() पृष्ठभूमि में अतिरिक्त कुछ किया था। new कीवर्ड ने एक नया ऑब्जेक्ट बनाया जो अब a1 संदर्भ देता है और वह ऑब्जेक्ट रिक्त है। इसके अलावा क्या हो रहा है:

हमने कहा है कि प्रत्येक फ़ंक्शन परिभाषा में एक नई प्रॉपर्टी बनाई गई है जिसे prototype कहा जाता है (जो आप इसे एक्सेस कर सकते हैं, __proto__ प्रॉपर्टी के विपरीत नहीं) बनाया गया है? ठीक है, उस संपत्ति का उपयोग अब किया जा रहा है

तो अब हम उस बिंदु पर हैं जहां हमारे पास ताजा बेक्ड खाली a1 ऑब्जेक्ट है। हमने कहा है कि जावास्क्रिप्ट के सभी ऑब्जेक्ट्स में एक आंतरिक __proto__ संपत्ति होती है जो कि कुछ ( a1 भी है) बताती है, चाहे वह रिक्त या दूसरी वस्तु है new ऑपरेटर क्या करता है कि यह निर्धारित करता है कि __proto__ प्रॉपर्टी फंक्शन के prototype प्रॉपर्टी को इंगित करती है। इसे फिर से पढ़ें यह मूल रूप से यह है:

 a1.__proto__ = A.prototype; 

हमने कहा है कि A.prototype एक खाली ऑब्जेक्ट से ज्यादा कुछ नहीं है (जब तक कि हम इसे 1 को परिभाषित करने से पहले कुछ और नहीं बदलते)। तो अब मूल रूप से a1.__proto__ एक ही बात A.prototype इंगित करता है, जो कि खाली वस्तु है वे दोनों एक ही वस्तु को इंगित करते हैं जो बनाया गया था जब यह रेखा हुई:

 A = function() {} // JS: cool. let's also create A.prototype pointing to empty {} 

अब, एक और चीज होती है जब var a1 = new A() स्टेटमेंट प्रोसेस किया जाता है। असल में A() निष्पादित होता है और अगर ए कुछ ऐसा होता है:

 var A = function() { this.hey = function() { alert('from A') } }; 

function() { } अंदर की सभी चीज़ें निष्पादित करने जा रही हैं। जब आप इस पर पहुंच this.hey.. रेखा, this में बदल जाती है और आप इसे प्राप्त करते हैं:

 a1.hey = function() { alert('from A') } 

मैं यह नहीं बताता कि this क्यों बदलता है, लेकिन यह जानने के लिए एक बहुत अच्छा जवाब है।

तो संक्षेप करने के लिए, जब आप “ var a1 = नया ए () करते हैं 'पृष्ठभूमि में 3 चीजें होती हैं:

  1. एक पूरी तरह से नया खाली ऑब्जेक्ट बनाया गया है और a1 को सौंपा गया है। a1 = {}
  2. a1.__proto__ प्रॉपर्टी को एक ही चीज़ को A.prototype अंक के रूप में इंगित करने के लिए सौंपा गया है (दूसरे खाली ऑब्जेक्ट {})

  3. फ़ंक्शन A() this सेट के साथ चरण 1 में बनाए गए नए, रिक्त ऑब्जेक्ट पर क्रियान्वित की जा रही है I

अब, एक और वस्तु बनाने का प्रयास करें:

 var a2 = new A(); 

चरण 1,2,3 फिर से दोहराना होगा। क्या आप कुछ नोटिस करते हैं? कुंजी शब्द दोहराना है। चरण 1: a2 एक नया खाली ऑब्जेक्ट होगा, चरण 2: इसकी __proto__ संपत्ति एक ही बात को इंगित A.prototype अंक और सबसे महत्वपूर्ण बात, चरण 3: फ़ंक्शन A() फिर से निष्पादित हो गया है, जिसका अर्थ है कि a2 को hey प्राप्त होगा एक फ़ंक्शन युक्त संपत्ति a1 और a2 पास दो अलग गुण हैं जो hey जो 2 अलग कार्यों को इंगित करता है! अब हमारे पास दो अलग-अलग ऑब्जेक्ट्स में डुप्लिकेट फ़ंक्शंस हैं, जो एक ही काम करते हैं, उफ़ … आप इस के स्मृति प्रभावों की कल्पना कर सकते हैं यदि हमारे पास new A के साथ बनाए गए 1000 ऑब्जेक्ट हैं, तो सभी फ़ंक्शन declarations संख्या 2 की तरह कुछ ज्यादा मेमोरी लेते हैं। । तो हम इसे कैसे रोकेंगे?

याद रखें कि __proto__ संपत्ति हर वस्तु पर क्यों मौजूद है? इसलिए यदि आप a1 (जो मौजूद नहीं है) पर yoMan संपत्ति को प्राप्त करते हैं, तो इसकी __proto__ सम्पत्ति से परामर्श किया जाएगा, यदि यह एक ऑब्जेक्ट है (और यह अधिकांश मामलों में है), यह जांच करेगा कि इसमें yoMan , और यदि यह नहीं, यह उस ऑब्जेक्ट के __proto__ आदि से परामर्श __proto__ । अगर ऐसा होता है, तो वह उस प्रॉपर्टी वैल्यू लेगा और इसे आपको प्रदर्शित करेगा।

इसलिए किसी ने इस तथ्य का उपयोग करने का निर्णय लिया + तथ्य यह है कि जब आप a1 बनाते हैं, तो इसकी __proto__ प्रॉपर्टी अंक समान (रिक्त) ऑब्जेक्ट A.prototype इंगित करते हैं और ऐसा करते हैं:

 var A = function() {} A.prototype.hey = function() { alert('from prototype') }; 

ठंडा! अब, जब आप a1 बनाते हैं, तो यह फिर से ऊपर के सभी 3 चरणों में जाता है, और चरण 3 में, यह कुछ नहीं करता, क्योंकि function A() को निष्पादित करने के लिए कुछ नहीं है। और अगर हम करें:

 a1.hey 

यह देखेगा कि a1 में hey शामिल नहीं है और यह इसकी __proto__ प्रॉपर्टी ऑब्जेक्ट की जांच करेगा कि यह क्या है, जो कि मामला है।

इस दृष्टिकोण के साथ हम चरण 3 से भाग को समाप्त करते हैं, जहां कार्यों को प्रत्येक नए ऑब्जेक्ट सृजन पर दोहराया जाता है। इसके बजाय a1 और a2 की एक अलग hey संपत्ति है, अब उनमें से कोई नहीं है जो, मुझे लगता है, अब आप ने खुद को सोचा है यह अच्छी बात है … अगर आप __proto__ और __proto__ समझते हैं, तो ये जैसे प्रश्न बहुत स्पष्ट होंगे।

नोट: कुछ लोग __proto__ रूप में आंतरिक प्रोटोटाइप सम्पत्ति को नहीं __proto__ , मैंने इस नाम को पोस्ट के माध्यम से स्पष्ट रूप से Functional.prototype संपत्ति को दो भिन्न चीजों के रूप में अलग करने के लिए उपयोग किया है।

ज्यादातर मामलों में वे अनिवार्य रूप से समान होते हैं, लेकिन दूसरा संस्करण स्मृति को बचाता है क्योंकि प्रत्येक ऑब्जेक्ट के लिए एक अलग फ़ंक्शन के बजाय फ़ंक्शन का केवल एक इंस्टेंस है

प्रथम फॉर्म का उपयोग करने का एक कारण "निजी सदस्य" का उपयोग करना है उदाहरण के लिए:

 var A = function () { var private_var = ...; this.x = function () { return private_var; }; this.setX = function (new_x) { private_var = new_x; }; }; 

जावास्क्रिप्ट के scoping नियमों के कारण, निजी_वर इस .x को निर्दिष्ट कार्य के लिए उपलब्ध है, लेकिन ऑब्जेक्ट से बाहर नहीं है

पहला उदाहरण केवल उस ऑब्जेक्ट के लिए अंतरफलक बदलता है। दूसरा उदाहरण उस वर्ग के सभी ऑब्जेक्ट के लिए इंटरफ़ेस को बदलता है।

prototype बजाए this का उपयोग this अंतिम समस्या this है कि जब एक विधि को ओवरराइड किया जाता है, तो बेस क्लास के कन्स्ट्रक्टर अभी भी ओवरराइड पद्धति का उल्लेख करेगा। इस पर विचार करो:

 BaseClass = function() { var text = null; this.setText = function(value) { text = value + " BaseClass!"; }; this.getText = function() { return text; }; this.setText("Hello"); // This always calls BaseClass.setText() }; SubClass = function() { // setText is not overridden yet, // so the constructor calls the superclass' method BaseClass.call(this); // Keeping a reference to the superclass' method var super_setText = this.setText; // Overriding this.setText = function(value) { super_setText.call(this, "SubClass says: " + value); }; }; SubClass.prototype = new BaseClass(); var subClass = new SubClass(); console.log(subClass.getText()); // Hello BaseClass! subClass.setText("Hello"); // setText is already overridden console.log(subClass.getText()); // SubClass says: Hello BaseClass! 

बनाम:

 BaseClass = function() { this.setText("Hello"); // This calls the overridden method }; BaseClass.prototype.setText = function(value) { this.text = value + " BaseClass!"; }; BaseClass.prototype.getText = function() { return this.text; }; SubClass = function() { // setText is already overridden, so this works as expected BaseClass.call(this); }; SubClass.prototype = new BaseClass(); SubClass.prototype.setText = function(value) { BaseClass.prototype.setText.call(this, "SubClass says: " + value); }; var subClass = new SubClass(); console.log(subClass.getText()); // SubClass says: Hello BaseClass! 

अगर आपको लगता है कि यह कोई समस्या नहीं है, तो यह इस बात पर निर्भर करता है कि आप निजी चर के बिना जीवित रह सकते हैं या नहीं, और चाहे आप एक को देखते हुए लीक को जानने के लिए पर्याप्त अनुभव कर रहे हों। इसके अलावा, विधि परिभाषा के बाद कन्स्ट्रक्टर लॉजिक रखना पड़ता है असुविधाजनक है।

 var A = function (param1) { var privateVar = null; // Private variable // Calling this.setPrivateVar(param1) here would be an error this.setPrivateVar = function (value) { privateVar = value; console.log("setPrivateVar value set to: " + value); // param1 is still here, possible memory leak console.log("setPrivateVar has param1: " + param1); }; // The constructor logic starts here possibly after // many lines of code that define methods this.setPrivateVar(param1); // This is valid }; var a = new A(0); // setPrivateVar value set to: 0 // setPrivateVar has param1: 0 a.setPrivateVar(1); //setPrivateVar value set to: 1 //setPrivateVar has param1: 0 

बनाम:

 var A = function (param1) { this.setPublicVar(param1); // This is valid }; A.prototype.setPublicVar = function (value) { this.publicVar = value; // No private variable }; var a = new A(0); a.setPublicVar(1); console.log(a.publicVar); // 1 

क्या फर्क पड़ता है? => बहुत कुछ

मुझे लगता है, this संस्करण का उपयोग एनकॅप्सुलेशन सक्षम करने के लिए किया जाता है, अर्थात डेटा छिपाना। यह निजी चर को हेरफेर करने में मदद करता है

हमें निम्नलिखित उदाहरण पर गौर करें:

 var AdultPerson = function() { var age; this.setAge = function(val) { // some housekeeping age = val >= 18 && val; }; this.getAge = function() { return age; }; this.isValid = function() { return !!age; }; }; 

अब, prototype संरचना निम्न के रूप में लागू किया जा सकता है:

अलग-अलग वयस्कों के पास अलग-अलग उम्र है, लेकिन सभी वयस्कों को समान अधिकार मिलते हैं।
इसलिए, हम इसे बजाय प्रोटोटाइप का उपयोग करते हैं।

 AdultPerson.prototype.getRights = function() { // Should be valid return this.isValid() && ['Booze', 'Drive']; }; 

अब कार्यान्वयन को देखने की सुविधा देता है

 var p1 = new AdultPerson; p1.setAge(12); // ( age = false ) console.log(p1.getRights()); // false ( Kid alert! ) p1.setAge(19); // ( age = 19 ) console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson ) var p2 = new AdultPerson; p2.setAge(45); console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it *** 

उम्मीद है की यह मदद करेगा।

प्रत्येक ऑब्जेक्ट प्रोटोटाइप ऑब्जेक्ट से जुड़ा हुआ है। जब ऐसी संपत्ति का उपयोग करने की कोशिश कर रही है जो मौजूद नहीं है, तो जावास्क्रिप्ट उस प्रॉपर्टी के लिए ऑब्जेक्ट के प्रोटोटाइप ऑब्जेक्ट में दिखेगा और यदि वह मौजूद है तो उसे वापस लौटा देगा।

फ़ंक्शन कन्स्ट्रक्टर की prototype प्रॉपर्टी का उपयोग करते हुए सभी आवृत्तियों के प्रोटोटाइप ऑब्जेक्ट को संदर्भित करता है जब कि new का उपयोग करते हुए


आपके पहले उदाहरण में, आप A फ़ंक्शन के साथ बनाए गए प्रत्येक उदाहरण के लिए प्रॉपर्टी x जोड़ रहे हैं।

 var A = function () { this.x = function () { //do something }; }; var a = new A(); // constructor function gets executed // newly created object gets an 'x' property // which is a function ax(); // and can be called like this 

दूसरे उदाहरण में आप प्रोटोटाइप ऑब्जेक्ट के लिए एक संपत्ति जोड़ रहे हैं जो सभी बिंदुओं को A बिंदु से बनाया गया है।

 var A = function () { }; A.prototype.x = function () { //do something }; var a = new A(); // constructor function gets executed // which does nothing in this example ax(); // you are trying to access the 'x' property of an instance of 'A' // which does not exist // so JavaScript looks for that property in the prototype object // that was defined using the 'prototype' property of the constructor 

अंत में, पहले उदाहरण में, समारोह की एक प्रति प्रत्येक आवृत्ति को सौंपा गया है । दूसरे उदाहरण में फ़ंक्शन की एक कॉपी सभी उदाहरणों से साझा की जाती है

मैं आपको एक अधिक व्यापक उत्तर देता हूं जो मैंने एक जावास्क्रिप्ट प्रशिक्षण पाठ्यक्रम के दौरान सीखा था।

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

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

आपने अपने प्रश्न में दो पैटर्न दिखाए मैं दो और अधिक समझने की कोशिश करूँगा और यदि प्रासंगिक हो तो अंतर को समझाने की कोशिश करेगी। संपादन / विस्तार करने के लिए स्वतंत्र महसूस करें सभी उदाहरणों में यह एक कार ऑब्जेक्ट के बारे में है जो कि एक स्थान है और स्थानांतरित हो सकता है।

ऑब्जेक्ट डेकोरेटर पैटर्न

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

 var carlike = function(obj, loc) { obj.loc = loc; obj.move = function() { obj.loc++; }; return obj; }; var amy = carlike({}, 1); amy.move(); var ben = carlike({}, 9); ben.move(); 

कार्यात्मक कक्षाएं

जावास्क्रिप्ट में एक फ़ंक्शन एक विशेष ऑब्जेक्ट है। लागू होने के अलावा, एक फ़ंक्शन किसी अन्य ऑब्जेक्ट की तरह गुणों को स्टोर कर सकता है।

इस मामले में Car एक फ़ंक्शन है ( ऑब्जेक्ट भी लगता है ) जो आपके लिए उपयोग की जाने वाली होती है इसमें संपत्ति के methods (जो एक move समारोह के साथ एक वस्तु है) है। जब Car को extend कार्य लागू किया जाता है, जो कुछ जादू करता है, और तरीकों के भीतर निर्धारित विधियों के साथ Car फ़ंक्शन (ऑब्जेक्ट लगता है) फैलता है

यह उदाहरण, हालांकि अलग है, प्रश्न में सबसे पहले उदाहरण के निकट आता है।

 var Car = function(loc) { var obj = {loc: loc}; extend(obj, Car.methods); return obj; }; Car.methods = { move : function() { this.loc++; } }; var amy = Car(1); amy.move(); var ben = Car(9); ben.move(); 

प्रोटोटाइप क्लासेस

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

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

हालांकि पता करने के लिए एक दिलचस्प बात यह है कि: प्रत्येक prototype ऑब्जेक्ट में एक सुविधा प्रॉपर्टी constructor , जो फ़ंक्शन (ऑब्जेक्ट को लगता है) से वापस जुड़ा हुआ है, जो इसे से जुड़ा हुआ था।

पिछले तीन पंक्तियों के संबंध में:

इस उदाहरण में, Car prototype ऑब्जेक्ट से लिंक, जो Car लिए constructor माध्यम से लिंक करता है, अर्थात Car.prototype.constructor Car ही है। यह आपको यह पता लगाने की अनुमति देता है कि कौन से कन्स्ट्रक्टर फ़ंक्शन ने एक निश्चित ऑब्जेक्ट बनाया है।

amy.constructor का लुकअप विफल रहता है और इस तरह Car.prototype को Car.prototype , जिसमें कन्स्ट्रक्टर संपत्ति होती है और इसलिए amy.constructoramy.constructor Car

इसके अलावा, amy एक instanceof Carinstanceof ऑपरेटर काम कर रहा है अगर सही ऑपरेंड के प्रोटोटाइप ऑब्जेक्ट ( Car ) को बाएं ऑपरेंड के प्रोटोटाइप ( amy ) श्रृंखला में कहीं भी मिल सकता है।

 var Car = function(loc) { var obj = Object.create(Car.prototype); obj.loc = loc; return obj; }; Car.prototype.move = function() { this.loc++; }; var amy = Car(1); amy.move(); var ben = Car(9); ben.move(); console.log(Car.prototype.constructor); console.log(amy.constructor); console.log(amy instanceof Car); 

कुछ डेवलपर्स को शुरुआत में भ्रमित किया जा सकता है उदाहरण नीचे देखें:

 var Dog = function() { return {legs: 4, bark: alert}; }; var fido = Dog(); console.log(fido instanceof Dog); 

instanceof ऑपरेटर को false रिटर्न देता false , क्योंकि Dog का प्रोटोटाइप fido प्रोटोटाइप श्रृंखला में कहीं भी नहीं मिल सकता है। fido एक साधारण ऑब्जेक्ट है जिसे किसी ऑब्जेक्ट के साथ बनाया गया है, अर्थात यह ऑब्जेक्ट के लिए केवल प्रतिनिधि है। Object.prototype

स्यूडोकास्लैसिक पैटर्न

यह वास्तव में सरल रूप में प्रोटोटाइप पैटर्न का एक और रूप है और उदाहरण के लिए जावा में कार्यक्रम करने वालों के लिए अधिक परिचित है, क्योंकि यह new कन्स्ट्रक्टर का उपयोग करता है।

यह वास्तव में प्रोटोटाइप पैटर्न के समान है, यह सिर्फ प्रोटोटाइप पैटर्न के ऊपर वाक्यविन्यास चीनी है।

हालांकि, प्राथमिक अंतर यह है कि जावास्क्रिप्ट इंजन में ऑप्टिमाइज़ेशन लागू किए गए हैं जो कि केवल छद्म-तरल पैटर्न का उपयोग करते समय लागू होते हैं प्रोटोटाइप पैटर्न की शायद एक तेज संस्करण के छद्म-प्रतिलिपि पैटर्न के बारे में सोचो; दोनों उदाहरणों में वस्तु संबंध समान हैं

 var Car = function(loc) { this.loc = loc; }; Car.prototype.move = function() { this.loc++; }; var amy = new Car(1); amy.move(); var ben = new Car(9); ben.move(); 

अंत में, यह एहसास करना बहुत कठिन नहीं होना चाहिए कि ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग कैसे किया जा सकता है। दो खंड हैं

एक खंड जो प्रोटोटाइप (श्रृंखला) में सामान्य गुणों / विधियों को परिभाषित करता है।

और एक अन्य खंड जिसमें आप परिभाषाएँ डालते हैं जो प्रत्येक दूसरे (उदाहरणों में loc चर) से वस्तुओं को अलग करती हैं।

यही हमें सुपरक्लास या जावास्क्रिप्ट में उप-वर्ग जैसी अवधारणाओं को लागू करने की अनुमति देता है।

जोड़ने या संपादित करने के लिए स्वतंत्र महसूस करें एक बार और पूरा होने पर मैं इसे एक सामुदायिक विकी बना सकता हूं।

प्रोटोटाइप क्लास का टेम्पलेट है; जो इसके सभी भविष्य के उदाहरणों पर लागू होता है जबकि यह वस्तु का विशेष उदाहरण है

मेरा मानना ​​है कि @ मैथ्यू क्रूमली सही है वे कार्यात्मक रूप से हैं , यदि संरचनात्मक रूप से नहीं, समकक्ष। यदि आप new वस्तुओं का उपयोग करके बनाई गई वस्तुओं को देखने के लिए फायरबग का उपयोग करते हैं, तो आप देख सकते हैं कि वे समान हैं। हालांकि, मेरी प्राथमिकता निम्नलिखित होगी: मुझे लग रहा है कि यह सिर्फ इतना ही लगता है कि मैं सी # / जावा में क्या इस्तेमाल कर रहा हूं। वह है, वर्ग को परिभाषित करें, खेतों, कन्स्ट्रक्टर, और विधियों को परिभाषित करें।

 var A = function() {}; A.prototype = { _instance_var: 0, initialize: function(v) { this._instance_var = v; }, x: function() { alert(this._instance_var); } }; 

EDIT Didn't mean to imply that the scope of the variable was private, I was just trying to illustrate how I define my classes in javascript. Variable name has been changed to reflect this.

As discussed in other answers, it's really a performance consideration because the function in the prototype is shared with all of the instantiations – rather than the function being created for each instantiation.

I put together a jsperf to show this. There is a dramatic difference in the time it takes to instantiate the class, although it is really only relevant if you are making many instances.

http://jsperf.com/functions-in-constructor-vs-prototype

I know this has been answered to death but I'd like to show an actual example of speed differences.

Function directly on object

Function on prototype

Here we're creating 2,000,000 new objects with a print method in Chrome. We're storing every object in an array. Putting print on the prototype takes about 1/2 as long.