2011-01-10 25 views
38

यह आपको व्याकरणिक रूप से गलत और संभवतः पागल प्रश्न के रूप में मार सकता है, लेकिन यहां मेरा मतलब है: जावास्क्रिप्ट में prototype की अवधारणा को समझने की कोशिश करते समय, मैं उन उदाहरणों पर आया जो निम्नलिखित के थोड़ा या कम जटिल संस्करण थे:जावास्क्रिप्ट प्रोटोटाइप क्यों है?

//Guitar function constructor 
function Guitar(color, strings) { 
    this.color = color; 
    this.strings = strings; 
} 
//Create a new instance of a Guitar 
var myGuitar = new Guitar('Black', ['D', 'A', 'D', 'F', 'A', 'E']); 
//Adding a new method to Guitar via prototype 
Guitar.prototype.play = function (chord) { 
    alert('Playing chord: ' + chord); 
}; 
//Now make use of this new method in a pre-declared instance 
myGuitar.play('D5'); 

तो, मेरी समस्या पर: आप यह क्यों करना चाहते हैं? आप play फ़ंक्शन को Guitar में क्यों शुरू नहीं करेंगे? एक उदाहरण घोषित क्यों करें और फिर बाद में विधियों को जोड़ने शुरू करें? एकमात्र कारण यह है कि यदि आप मूल रूप से बनाए गए play तक पहुंच नहीं पाते हैं, तो मैं myGuitar पर पहुंचने के लिए चाहता हूं, लेकिन मैं ऐसा कोई उदाहरण नहीं दे सकता हूं कि आप इस तरह कुछ क्यों चाहते हैं।

ऐसा लगता है कि यह यह करने के लिए और अधिक समझ बनाने जाएगा लगता है:

function Guitar(color, string) { 
    this.color = color; 
    this.strings = strings; 
    this.play = function (chord) { 
     alert('Playing chord: ' + chord); 
    }; 
} 
var myGuitar = new Guitar('White', ['E', 'A', 'D', 'G', 'B', 'E']); 
myGuitar.play('E7#9'); 

वास्तविक समस्या है कि यहाँ दूसरे उदाहरण जबकि पहला उदाहरण नहीं है मेरे लिए समझ में आता है, जबकि वास्तव में, पहले उदाहरण शायद किसी कारण से बेहतर है। दुर्भाग्यवश, मैंने जो भी ट्यूटोरियल कभी पाया है, वह prototype का उपयोग करने के चरणों के माध्यम से जाता है, लेकिन क्यों नहीं prototype पैराडाइम शुरू करने के लिए बिल्कुल मौजूद है।

ऐसा लगता है कि prototype आपको ऐसी चीजें करने की अनुमति देता है जो आप अन्यथा करने में सक्षम नहीं होंगे, लेकिन मैं इन्हें क्यों करना चाहूंगा, इस बारे में कोई अच्छा कारण नहीं है।

संपादित करें: कुछ प्रतिक्रियाएं:

  • जब मैं ने कहा, "क्यों एक उदाहरण की घोषणा और फिर बाद में तरीकों जोड़ना शुरू?" मैं उन सभी उदाहरणों की आलोचना करता हूं जो मैं देखता हूं जो मेरे पहले उदाहरण के क्रम में खेलते हैं। जब यह आदेश बदल जाता है, जैसा कि हर्मन की प्रतिक्रिया में नीचे है, यह थोड़ा और अधिक दृष्टि से समझ में आता है। हालांकि, यह इस तथ्य को नहीं बदलेगा कि, मेरे पहले उदाहरण के समान ही, आप एक खाली ऑब्जेक्ट फ़ंक्शन कन्स्ट्रक्टर बना सकते हैं, इस ऑब्जेक्ट के 100 उदाहरण घोषित कर सकते हैं, और उसके बाद केवल मूल वस्तु को वास्तविक रूप से परिभाषित करें द्वारा prototype के माध्यम से इसे विधियों और गुणों को दे रहा है। शायद यह आमतौर पर नीचे उल्लिखित प्रति बनाम संदर्भ विचार पर संकेत देने के लिए इस तरह से किया जाता है।
  • कई प्रतिक्रियाओं के आधार पर, मेरी नई समझ यहां दी गई है: यदि आप ऑब्जेक्ट फ़ंक्शन कन्स्ट्रक्टर को अपनी सभी गुणों और विधियों को जोड़ते हैं, तो उस ऑब्जेक्ट के 100 उदाहरण बनाएं, आपको सभी गुणों और विधियों की 100 प्रतियां मिलती हैं। इसके बजाय, यदि आप ऑब्जेक्ट फ़ंक्शन कन्स्ट्रक्टर के prototype पर अपनी सभी गुणों और विधियों को जोड़ते हैं, तो उस ऑब्जेक्ट के 100 उदाहरण बनाएं, आपको ऑब्जेक्ट की गुणों और विधियों की एकल (1) प्रतिलिपि में 100 संदर्भ प्राप्त करें। यह स्पष्ट रूप से तेज़ और अधिक कुशल है और इसलिए prototype का उपयोग किया जाता है (नीचे उल्लिखित String और Image जैसी चीजों को बदलने से अलग)। तो, क्यों ऐसा नहीं:

function Guitar(color, strings) { 
    this.prototype.color = color; 
    this.prototype.strings = strings; 
    this.prototype.play = function (chord) { 
     alert('Playing chord: ' + chord); 
    }; 
} 
var myGuitar = new Guitar('Blue', ['D', 'A', 'D', 'G', 'B', 'E']); 
myGuitar.play('Dm7'); 
+0

मैं अपने संपादन के लिए मेरा उत्तर अद्यतन करना चाहिए। – hvgotcodes

उत्तर

1

एक बात के लिए, (बुलेटेड सूची उनके पीछे सही किसी भी कोड को तोड़ने, जाहिरा तौर पर, तो मैं अलग-अलग पाठ यहाँ की एक पंक्ति जोड़ने के लिए) आप कर सकते हैं जावास्क्रिप्ट भाषा (जैसे स्ट्रिंग) में बनाए गए ऑब्जेक्ट्स को विस्तारित करने के लिए प्रोटोटाइप का उपयोग करें। मैं कस्टम ऑब्जेक्ट्स के लिए दूसरा उदाहरण पसंद करता हूं।

24

तो, मेरी समस्या पर: आप यह क्यों करना चाहते हैं? आप शुरू करने के लिए गिटार में नाटक समारोह क्यों नहीं लगाएंगे? एक उदाहरण घोषित क्यों करें और फिर बाद में विधियों को जोड़ने शुरू करें?

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

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

अंतर देखें। जब भी आप एक नया गिटार बनाते हैं, तो 'इस तरह क्यों नहीं' उदाहरण पोस्ट करते हैं, आपको एक नई प्ले विधि बनाने की आवश्यकता होती है जो हर दूसरे प्ले विधि के समान होती है। यदि नाटक प्रोटोटाइप पर है, हालांकि, सभी गिटार एक ही प्रोटोटाइप से उधार लेते हैं, इसलिए वे सभी एक ही कोड को खेलने के लिए साझा करते हैं। x गिटार की संख्या के बीच अंतर, प्रत्येक समान प्ले कोड के साथ (इसलिए आपके पास x नाटक की प्रतियां हैं) बनाम x समान प्ले कोड साझा करने वाले गिटार की संख्या (खेल की एक प्रति चाहे कितने गिटार हों) । व्यापार बंद यह है कि रनटाइम प्ले पर उस ऑब्जेक्ट से जुड़ा होना चाहिए जिस पर उसे स्कोपिंग के लिए बुलाया जाता है, लेकिन जावास्क्रिप्ट में ऐसे विधियां हैं जो आपको बहुत कुशलतापूर्वक और आसानी से करने की अनुमति देती हैं (अर्थात् call और apply विधियां)

कई जावास्क्रिप्ट ढांचे 'वर्ग' बनाने के लिए अपनी स्वयं की उपयोगिता को परिभाषित करते हैं। आम तौर पर वे आपको उदाहरण लिखने की अनुमति देते हैं जैसे आपने कहा था कि आप देखना चाहते हैं। दृश्यों के पीछे, वे आपके लिए प्रोटोटाइप पर फ़ंक्शंस डाल रहे हैं।


संपादित करें - अपने अद्यतन सवाल का जवाब में, क्यों

function Guitar() { 
    this.prototype.play = function().... 
} 

यह कैसे जावास्क्रिप्ट 'नए' कीवर्ड के साथ वस्तुओं बनाता है के साथ क्या करना है क्या नहीं एक कर सकते हैं। दूसरा उत्तर here देखें - मूल रूप से जब आप कोई उदाहरण बनाते हैं, जावास्क्रिप्ट ऑब्जेक्ट बनाता है और तब प्रोटोटाइप गुण निर्दिष्ट करता है। तो यह .prototype.play वास्तव में समझ में नहीं आता है; वास्तव में, यदि आप इसे आजमाते हैं तो आपको एक त्रुटि मिलती है।

1

जावास्क्रिप्ट प्रोटोटाइप आधारित है। रोम में, जब रोम में ऐसा होता है तो जेएस में प्रोटोटाइप विरासत का उपयोग करें।

यह अधिक कुशल है क्योंकि विधि प्रत्येक वस्तु पर विरासत में प्राप्त होती है। यदि यह प्रोटोटाइप विधि नहीं था तो प्रत्येक उस ऑब्जेक्ट का उदाहरण प्रत्येक के पास play विधि होगी। जेएस रूट के लिए अक्षम और प्राकृतिक क्यों जा सकते हैं जब हम जेएस रूट के लिए कुशल और प्राकृतिक जा सकते हैं?

+2

किसी को यह भी ध्यान रखना चाहिए कि यह शास्त्रीय मॉडल की तुलना में अधिक शक्तिशाली है, उदा। आप जेएस में क्लासिक को काफी आसान बना सकते हैं, हालांकि दूसरी तरफ काफी जटिल है। –

2

पहली विधि आप दे तेजी से होता है, और यह वास्तव में समझ बनाने के लिए जब आप एक अन्य आदेश में लिखने शुरू होता है:

//Guitar function constructor 
function Guitar(color, strings) { 
    this.color = color; 
    this.strings = strings; 
} 

Guitar.prototype.play = function (chord) { 
    alert('Playing chord: ' + chord); 
}; 

var myGuitar = new Guitar('Black', ['D', 'A', 'D', 'F', 'A', 'E']); 

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

एक सबूत के लिए, see this speed test इस प्रश्न पर बहुत अधिक है।


और शायद इस वैकल्पिक संस्करण आप और भी अधिक समझ में आता है:

function Guitar(){ 
    // constructor 
} 

Guitar.prototype = { 
    play: function(a){ 
    alert(a); 
    }, 

    stop: function(){ 
    alert('stop it'); 
    } 
}; 
+0

पूरे प्रोटोटाइप को ओवरराइट करने से ऑब्जेक्ट के साथ झुकाव गिर जाएगी, जो हमेशा प्रोटोटाइप पर होने वाली चीजों को दूर करते हैं? – hvgotcodes

+1

@hvgotcodes: यह परिवर्तन के बाद बनाए गए उदाहरणों के लिए प्रोटोटाइप बदल देगा। लेकिन यह पहले से मौजूद मौजूदा मामलों के लिए कुछ भी नहीं बदलेगा। वे अभी भी मूल प्रोटोटाइप का संदर्भ है। –

1

आप पहले से ही है यही कारण है कि मैं अपने अंक सभी के माध्यम से नहीं जा रहा हूँ अच्छा जवाब में से एक बहुत कुछ है।

क्यों एक उदाहरण घोषित करें और फिर बाद में विधियों को जोड़ने शुरू करें?

यह सही नहीं है। प्रोटोटाइप ऑब्जेक्ट प्रत्येक उदाहरण के स्वतंत्र रूप से मौजूद है। यह फ़ंक्शन ऑब्जेक्ट (कन्स्ट्रक्टर फ़ंक्शन) की संपत्ति है।
जब आप एक नया उदाहरण बनाते हैं तो यह प्रोटोटाइप से सभी गुणों को "विरासत" देता है (वास्तव में, इसका संदर्भ है)।

वास्तव में यह समझ में आता है अगर आप वस्तुओं और संदर्भ के बारे में सोचना: यह बेहतर (स्मृति के लिहाज से) एक वस्तु की अपनी एक प्रतिलिपि (इस मामले में वस्तु होने प्रत्येक उदाहरण से एक वस्तु को शेयर एक संदर्भ है होगा फंक्शन play हो)।

क्यों प्रोटोटाइप आधारित है: आप यह भी पूछ सकते हैं कि विभिन्न भाषा प्रतिमान मौजूद क्यों हैं (कार्यात्मक, ओओ, घोषणात्मक)। कुछ कुछ करने के लिए केवल एक सही तरीका नहीं है।

1

यह प्रोटोटाइप रचनात्मक डिजाइन पैटर्न पर आधारित है। इस विकिपीडिया लिंक की एक अच्छी चर्चा है।

http://en.wikipedia.org/wiki/Prototype_pattern

+0

@ बीजे - आपके द्वारा लिंक किए गए विकिपीडिया पेज में उदाहरण जावा में है, जावास्क्रिप्ट नहीं। क्या आप किसी अन्य लेख से लिंक करना चाहते थे? –

+0

@ जॉन - नहीं। एक संकलन के दौरान एक जवाब में निचोड़ने की कोशिश करने के लिए मुझे यही मिलता है। मैंने ग़लत बयान हटा दिया। धन्यवाद। –

+0

मेरी पिछली त्रुटि के लिए कुछ तपस्या के रूप में, यहां एक अच्छी पिछली SO चर्चा है। स्टीव येगेज के ब्लॉग पर लिंक का पालन करना सुनिश्चित करें और प्रोटोटाइप की चर्चा पढ़ें; गोडेल, एस्चर, & Bach; और बाकी के साथ फुटबॉल खिलाड़ी। http://stackoverflow.com/questions/228134/how-does-yegges-prototype-pattern-example-handle-instance-variables –

3

आप प्रोटोटाइप का उपयोग नहीं करते हैं, तो हर बार जब आप गिटार के निर्माता कहते हैं, आप एक नया समारोह पैदा करेगा। यदि आप बहुत सारे गिटार ऑब्जेक्ट्स बना रहे हैं, तो आप प्रदर्शन में एक अंतर देखेंगे।

प्रोटोटाइप का उपयोग करने का एक अन्य कारण शास्त्रीय विरासत का अनुकरण करना है।

var Instrument = { 
    play: function (chord) { 
     alert('Playing chord: ' + chord); 
    } 
}; 

var Guitar = (function() { 
    var constructor = function(color, strings) { 
     this.color = color; 
     this.strings = strings; 
    }; 
    constructor.prototype = Instrument; 
    return constructor; 
}()); 

var myGuitar = new Guitar('Black', ['D', 'A', 'D', 'F', 'A', 'E']); 
myGuitar.play('D5'); 

इस उदाहरण में, गिटार इंस्ट्रूमेंट फैलाता है, और इसलिए 'प्ले' फ़ंक्शन होता है। यदि आप चाहें तो गिटार में इंस्ट्रूमेंट के 'प्ले' फ़ंक्शन को ओवरराइड भी कर सकते हैं।

3

जावास्क्रिप्ट एक प्रोटोटाइपिकल भाषा है, बल्कि दुर्लभ नस्ल है। यह मनमाने ढंग से नहीं है, यह एक ऐसी भाषा की आवश्यकता है जिसका मूल्यांकन किया गया है और "eval", गतिशील संशोधन और REPL के सक्षम है।

प्रोटोटाइपिकल उत्तराधिकारी को ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग की तुलना में स्थिर पूर्वनिर्धारित लोगों की बजाय रनटाइम "लाइव" क्लास परिभाषाओं के आधार पर समझा जा सकता है।

संपादित करें: निम्न लिंक से चोरी की गई एक और स्पष्टीकरण भी उपयोगी है। ऑब्जेक्ट ओरिएंटेड लैंग्वेज (क्लास -> ऑब्जेक्ट/इंस्टेंस) में किसी दिए गए एक्स के सभी संभावित गुण क्लास एक्स में उल्लिखित हैं, और एक उदाहरण उनमें से प्रत्येक के लिए अपने विशिष्ट मानों में भर जाता है। प्रोटोटाइपिकल विरासत में आप केवल अंतर का वर्णन लाइव एक्स के मौजूदा संदर्भ और समान लेकिन अलग लाइव वाई के बीच करते हैं, और मास्टर कॉपी नहीं है।

http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html

सबसे पहले आप संदर्भ समझने की जरूरत है। जावास्क्रिप्ट एक व्याख्या की गई भाषा है जिसे निष्पादित किया जाता है और इसे लाइव वातावरण में संशोधित किया जा सकता है। कार्यक्रम की आंतरिक संरचना को रनटाइम पर संशोधित किया जा सकता है। यह किसी भी संकलित भाषा से अलग बाधाओं और फायदे रखता है, या यहां तक ​​कि सीएलआर लिंक्ड भाषा जैसे नेट सामग्री।

"eval"/REPL की अवधारणा गतिशील परिवर्तनीय टाइपिंग की आवश्यकता है। आप ऐसे माहौल को प्रभावी ढंग से लाइव-एडिट नहीं कर सकते जहां आपको पूर्वनिर्धारित क्लास आधारित विरासत संरचनाएं पूर्वनिर्धारित करनी होंगी। यह व्यर्थ है, आप असेंबली या बाइटकोड के लिए बस precompile हो सकता है।

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

इस रणनीति के साथ जावास्क्रिप्ट मूल रूप से "लाइव" होने पर सबकुछ बैंकों से कुछ भी सीमा नहीं है, वहां कोई "परिभाषित और पूर्ण" कक्षाएं नहीं हैं जिन्हें आप कभी भी स्पर्श नहीं कर सकते हैं। चर के बीच कोई "एक ट्रू स्कॉट्समेन" नहीं है जो आपके कोड की तुलना में पवित्र है क्योंकि सब कुछ उसी नियम के समान नियमों का पालन करता है जैसा आप आज लिखने का निर्णय लेते हैं।

इसका परिणाम स्पष्ट है, और यह भी बहुत अधिक मानव आधारित है। यह मूल वस्तुओं को प्रदान करने में एक हल्का, कुशल स्पर्श का उपयोग करने के लिए भाषा कार्यान्वयन को धक्का देता है। यदि वे एक गरीब नौकरी करते हैं तो भीड़ मंच को केवल उतार-चढ़ाव करेगी और अपना खुद का पुनर्निर्माण करेगी (म्यूटूल के स्रोत को पढ़ें, यह सचमुच फंक्शन और ऑब्जेक्ट से शुरू होने वाली सभी चीजों को फिर से परिभाषित/पुन: लागू करता है)। इस तरह पुराने इंटरनेट एक्सप्लोरर संस्करणों जैसे प्लेटफॉर्म पर संगतता लाई जाती है। यह पुस्तकालयों को बढ़ावा देता है जो उथले और संकीर्ण, घनी कार्यात्मक होते हैं। दीप विरासत के परिणामस्वरूप सबसे अधिक इस्तेमाल किए जाने वाले हिस्सों (आसानी से) चेरी को चुना जाता है और अंतिम गो-लाइब्रेरी बन जाता है। व्यापक पुस्तकालयों में फ्रैक्चरिंग होती है क्योंकि लोग चुनते हैं और चुनते हैं कि उन्हें किस टुकड़े की आवश्यकता है, क्योंकि काटने से बाहर निकलना आसान है, बल्कि अधिकांश अन्य वातावरण में असंभव है।

सूक्ष्म पुस्तकालयों की अवधारणा जावास्क्रिप्ट में विशिष्ट रूप से बढ़ रही है और इसे पूरी तरह से भाषा के मूलभूत सिद्धांतों पर देखा जा सकता है। यह मानवीय खपत के संदर्भ में दक्षता और अल्पसंख्यक को प्रोत्साहित करता है, जिस तरह से कोई अन्य भाषा (जिसे मैं जानता हूं) को बढ़ावा देता हूं।

12

शुरुआत से पहले एक नोट के रूप में - मैं जावास्क्रिप्ट के बजाय एक्शनस्क्रिप्ट 1 और 2 प्रदर्शन बिल्कुल रनटाइम पर समान व्यवहार के रूप में ईसीएमएस्क्रिप्ट का उपयोग कर रहा हूं।

हम में से जो लोग "पारंपरिक" ऑब्जेक्ट उन्मुख दुनिया (जावा/सी #/पीएचपी पढ़ते हैं) में काम करते हैं, वे लगभग पूरी तरह विदेशी रूप से रनटाइम पर कक्षा को विस्तारित करने का विचार पाते हैं। मेरा मतलब है, गंभीरता से, यह मेरा उद्देश्य माना जाता है। मेरा उद्देश्य आगे बढ़ेगा और चीजें करें जो सेट फॉर हैं। बाल वर्ग EXTEND अन्य क्लास। इसमें पत्थर की भावना में एक बहुत ही संरचित, ठोस, सेट है। और, अधिकांश भाग के लिए, यह काम करता है और यह काफी अच्छी तरह से काम करता है।(और यह कारण है कि गोस्लिंग ने तर्क दिया है, और मुझे लगता है कि हम में से अधिकांश काफी प्रभावी ढंग से सहमत होंगे, यह बड़े पैमाने पर सिस्टम के लिए बहुत उपयुक्त है)

दूसरी तरफ ईसीएमएस्क्रिप्ट, एक और अधिक प्राथमिक अवधारणा का पालन करता है ओओपी का ईसीएमएस्क्रिप्ट में, वर्ग विरासत पूरी तरह से है, मान लीजिए या नहीं, एक विशाल सजावटी पैटर्न। लेकिन यह सिर्फ सजावटी पैटर्न नहीं है जो आप कह सकते हैं सी ++ और पायथन में मौजूद है (और आप आसानी से कह सकते हैं कि वे सजावटी हैं)। ईसीएमएस्क्रिप्ट आपको एक उदाहरण के लिए कक्षा प्रोटोटाइप असाइन करने देता है।

जावा में हो रहा कल्पना कीजिए:

class Foo { 
    Foo(){} 
} 

class Bar extends new Foo() { 
    // AAAHHHG!!!! THE INSANITY! 
} 

लेकिन, वह यह है कि वास्तव में क्या ECMAScript में उपलब्ध है (मेरा मानना ​​है कि आईओ भी कुछ इस तरह के लिए अनुमति देता है, लेकिन मेरे बोली नहीं है)।

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

तो, दिन में वापस, एलोनोजो चर्च ने The Calculi Lambda Conversion लिखा, लैम्ब्डा कैलकुस में मौलिक कार्य। इसमें वह बहु-तर्क कार्यों को देखने के दो तरीकों का प्रस्ताव करता है। सबसे पहले, उन्हें ऐसे कार्य माना जा सकता है जो सिंगलेट, टुपल्स, ट्रिपल इत्यादि को स्वीकार करते हैं। मूल रूप से एफ (एक्स, वाई, जेड) को एफ के रूप में समझा जाएगा जो पैरामीटर (x, y, z) स्वीकार करता है। (वैसे, यह मेरी विनम्र राय है कि यह पाइथन की तर्क सूचियों की संरचना के लिए एक प्राथमिक प्रेरणा है, लेकिन यह अनुमान है)।

अन्य (और हमारे उद्देश्यों के लिए (और, ईमानदार, चर्च के उद्देश्यों के लिए) अधिक महत्वपूर्ण) परिभाषा मैककार्थी द्वारा उठाई गई थी। एफ (एक्स, वाई, जेड) का अनुवाद एफ (एक्स जी (वाई एच (जेड)) के बजाय किया जाना चाहिए)। बाहरीतम विधि का संकल्प उन राज्यों की एक श्रृंखला से आ सकता है जो आंतरिक फ़ंक्शन कॉल द्वारा उत्पन्न किए गए थे। संग्रहीत, आंतरिक राज्य बंद होने का आधार है, जो बदले में, आधुनिक ओओपी के आधारों में से एक है। बंदरगाह विभिन्न बिंदुओं के बीच संलग्न, निष्पादन योग्य राज्यों को पारित करने की अनुमति देता है।

पुस्तक लिस्प की जमीन के एक मोड़ सौजन्य:

; Can you tell what this does? It it is just like your favorite 
; DB’s sequence! 
; (getx) returns the current value of X. (increment) adds 1 to x 
; The beauty? Once the let parens close, x only exists in the 
; scope of the two functions! passable enclosed executable state! 
; It is amazingly exciting! 
(let (x 0) 
    ; apologies if I messed up the syntax 
    (defun increment()(setf x (+ 1 x))) 
    (defun getx()(x))) 

अब, क्या इस ECMAScript बनाम जावा के साथ क्या करना है? खैर, जब एक वस्तु ECMAScript में बन जाता है यह लगभग ठीक है कि पैटर्न का पालन कर सकते हैं:

function getSequence() 
{ 
    var x = 0; 
    function getx(){ return x } 
    function increment(){ x++ } 
    // once again, passable, enclosed, executable state 
    return { getX: getX, increment:increment} 
} 

और यहाँ जहां प्रोटोटाइप ECMAScript में विरासत में आने का मतलब है, शुरू होता है। "वस्तु एक साथ शुरू करने और इसे करने के लिए जोड़ सकते हैं।" यह इसकी प्रतिलिपि नहीं है। यह जादुई राज्य लेता है और ईसीएमएस्क्रिप्ट इसे जोड़ता है। और यह MyClass.prototype.foo = 1 के लिए अनुमति देने का बहुत स्रोत और शिखर सम्मेलन है।

क्यों आप "तथ्य के बाद" तरीकों को जोड़ देंगे। अधिकांश भाग के लिए यह वास्तव में शैली प्राथमिकताओं के लिए उबाल जाता है। मूल परिभाषा के अंदर जो कुछ भी होता है वह उसी प्रकार की सजावट से अधिक नहीं कर रहा है जो बाहर होता है।

अधिकांश भाग के लिए यह आपकी सभी परिभाषाओं को एक ही स्थान पर रखने के लिए स्टाइलिस्टिक रूप से फायदेमंद है, लेकिन कभी-कभी यह संभव नहीं है। jQuery एक्सटेंशन, उदाहरण के लिए, jQuery ऑब्जेक्ट प्रोटोटाइप को सीधे जोड़ने के विचार के आधार पर काम करते हैं। प्रोटोटाइप लाइब्रेरी में वास्तव में कक्षा परिभाषाओं का विस्तार करने का एक विशेष तरीका है जो लगातार उपयोग करता है।

यदि मुझे प्रोटोटाइप याद है।js सही ढंग से, यह कुछ इस तरह है:

var Sequence = function(){} 

// Object.extend takes all keys & values from the right object and 
// adds them to the one on the left. 
Object.extend(Sequence.prototype, (function() 
{ 
    var x = 0; 
    function getx(){ return x } 
    function increment(){ x++ } 
    return { getX: getX, increment:increment} 
    })()); 

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

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

// set the id of all instances of this “class”. Event those already 
// instantiated... 
this.constructor.prototype.id = 2 
console.log(this.id); 
+0

वाह। इतिहास सबक के लिए धन्यवाद :-) – Peter

+0

@cwallenpoole यह एक भयानक स्पष्टीकरण था और मैं इस विषय पर ऐसे सूचनात्मक और आसानी से समझने के लिए पोस्ट करने के लिए समय निकालने के लिए धन्यवाद देना चाहता हूं। – Typo

-1

भाई मैं आपको एक बात है, क्या आप गिटार, Casio, वायलिन है और यदि आप इनमें से संगीत वाद्ययंत्र में से प्रत्येक में एक ही chords खेलने चाहते पूछना करते हैं।

तो मुझे लगता है कि हम अलग-अलग फ़ंक्शन play_chord क्यों नहीं रखते हैं और गिटार, कैसीओ या वायलिन के अंदर प्रत्येक फ़ंक्शन का उपयोग करने के बजाय उपरोक्त किसी भी उपकरण के साथ इस (play_chord) फ़ंक्शन का उपयोग नहीं करते हैं।

तो अंत में जब भी हम एक समारोह है जो अन्य निर्माता का हिस्सा हो सकता की जरूरत है तो हम उस विशेष समारोह प्रोटोटाइप अंदर परिभाषित करने और तदनुसार का उपयोग :)

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