मैं जावास्क्रिप्ट के पर्दे के पर्दे के पीछे समझने की कोशिश कर रहा हूं और वस्तुओं में निर्मित, विशेष रूप से ऑब्जेक्ट और फंक्शन और उनके बीच के संबंध को समझने में अटक गया।
यह जटिल है, गलतफहमी करना आसान है, और एक बहुत से शुरुआती जावास्क्रिप्ट किताबें गलत हैं, इसलिए पढ़ी गई हर चीज पर भरोसा न करें।
मैं 1990 के दशक में Microsoft के JS इंजन के मानकीकरण और मानकीकरण समिति में से एक था, और मैंने इस उत्तर को डालने में कई गलतियाँ कीं। (हालांकि मैंने 15 साल से इस पर काम नहीं किया है लेकिन मुझे माफ किया जा सकता है।) यह मुश्किल भरा काम है। लेकिन एक बार जब आप प्रोटोटाइप इनहेरिटेंस को समझ लेते हैं, तो यह सब समझ में आता है।
जब मैंने पढ़ा कि Array, String इत्यादि में निर्मित सभी ऑब्जेक्ट ऑब्जेक्ट से एक्सटेंशन (इनहेरिट की गई) हैं तो मैंने मान लिया कि ऑब्जेक्ट ऑब्जेक्ट में पहला बनाया गया है जो कि निर्मित होता है और बाकी ऑब्जेक्ट इससे प्राप्त होता है।
कक्षा-आधारित विरासत के बारे में जो कुछ भी आप जानते हैं, उसे फेंककर शुरू करें। JS प्रोटोटाइप आधारित विरासत का उपयोग करता है।
इसके बाद, सुनिश्चित करें कि आपके सिर में बहुत स्पष्ट परिभाषा है कि "विरासत" का क्या अर्थ है। C # या Java या C ++ जैसी OO भाषाओं का उपयोग करने वाले लोग सोचते हैं कि इनहेरिटेंस का अर्थ सबटाइपिंग है, लेकिन इनहेरिटेंस का मतलब सबटिप करना नहीं है। वंशानुक्रम का अर्थ है कि एक चीज के सदस्य दूसरी चीज के सदस्य भी हैं । यह नहीं है जरूरी मतलब उन चीजों के बीच एक subtyping रिश्ता होता है कि! टाइप थ्योरी में बहुत सी गलतफहमियां लोगों को यह अहसास नहीं होने का नतीजा है कि इसमें अंतर है।
लेकिन इसका कोई मतलब नहीं है जब आपको पता चले कि ऑब्जेक्ट केवल फ़ंक्शन द्वारा बनाए जा सकते हैं, लेकिन फिर फ़ंक्शन भी कुछ नहीं बल्कि फ़ंक्शन की वस्तुएं हैं।
यह केवल झूठ है। कुछ फ़ंक्शन के लिए कॉल करके कुछ ऑब्जेक्ट नहीं बनाए जाते हैं । कुछ वस्तुओं को जेएस रनटाइम द्वारा बिल्कुल भी नहीं बनाया जाता है। ऐसे अंडे हैं जो किसी भी चिकन द्वारा नहीं रखे गए थे । वे सिर्फ रनटाइम द्वारा बनाए गए थे जब यह शुरू हुआ था।new FF
आइए बताते हैं कि नियम क्या हैं और शायद इससे मदद मिलेगी।
- हर ऑब्जेक्ट इंस्टेंस में एक प्रोटोटाइप ऑब्जेक्ट होता है।
- कुछ मामलों में जो प्रोटोटाइप हो सकते हैं
null।
- यदि आप किसी ऑब्जेक्ट उदाहरण पर किसी सदस्य तक पहुँचते हैं, और ऑब्जेक्ट में वह सदस्य नहीं है, तो ऑब्जेक्ट उसके प्रोटोटाइप में ख़राब हो जाता है, या यदि प्रोटोटाइप शून्य है तो रुक जाता है।
prototypeएक वस्तु का सदस्य आमतौर पर है नहीं वस्तु के प्रोटोटाइप।
- बल्कि,
prototypeएक फंक्शन ऑब्जेक्ट F का सदस्य वह ऑब्जेक्ट है जो द्वारा बनाई गई ऑब्जेक्ट का प्रोटोटाइप बन जाएगा new F()।
- कुछ कार्यान्वयन में, उदाहरणों को एक
__proto__सदस्य मिलता है जो वास्तव में अपना प्रोटोटाइप देता है। (यह अब हटा दिया गया है। इस पर भरोसा न करें।)
- फंक्शन ऑब्जेक्ट्स को एक नई-नई डिफ़ॉल्ट ऑब्जेक्ट मिलती है,
prototypeजब उन्हें बनाया जाता है।
- एक फंक्शन ऑब्जेक्ट का प्रोटोटाइप निश्चित रूप से है
Function.prototype।
चलो योग करो।
- का प्रोटोटाइप
ObjectहैFunction.prototype
Object.prototype ऑब्जेक्ट प्रोटोटाइप ऑब्जेक्ट है।
- का प्रोटोटाइप
Object.prototypeहैnull
- का प्रोटोटाइप
Functionहै Function.prototype- यह उन दुर्लभ स्थितियों में से एक है जहां Function.prototypeवास्तव में प्रोटोटाइप है Function!
Function.prototype फ़ंक्शन प्रोटोटाइप ऑब्जेक्ट है।
- का प्रोटोटाइप
Function.prototypeहैObject.prototype
मान लीजिए कि हम एक फ़ंक्शन फू बनाते हैं।
- का प्रोटोटाइप
Fooहै Function.prototype।
Foo.prototype फू प्रोटोटाइप वस्तु है।
- का प्रोटोटाइप
Foo.prototypeहै Object.prototype।
मान लीजिए हम कहते हैं new Foo()
- नई वस्तु का प्रोटोटाइप है
Foo.prototype
सुनिश्चित करें कि समझ में आता है। चलो इसे ड्रा करें। अंडाकार वस्तु उदाहरण हैं। किनारे या तो __proto__अर्थ हैं "का प्रोटोटाइप", या prototypeअर्थ "की prototypeसंपत्ति"।

सभी रनटाइम को उन सभी ऑब्जेक्ट्स को बनाना होगा और तदनुसार अपने विभिन्न गुणों को असाइन करना होगा। मुझे यकीन है कि आप देख सकते हैं कि यह कैसे किया जाएगा।
अब आइए एक उदाहरण देखें जो आपके ज्ञान का परीक्षण करता है।
function Car(){ }
var honda = new Car();
print(honda instanceof Car);
print(honda.constructor == Car);
यह क्या छपता है?
खैर, क्या instanceofमतलब है? honda instanceof Carइसका मतलब है " प्रोटोटाइप श्रृंखला Car.prototypeपर किसी भी वस्तु के बराबर है honda?"
हाँ यही है। hondaप्रोटोटाइप है Car.prototype, तो हम कर रहे हैं। यह सच छापता है।
दूसरे के बारे में क्या?
honda.constructorमौजूद नहीं है इसलिए हम प्रोटोटाइप से सलाह लेते हैं, जो है Car.prototype। जब Car.prototypeऑब्जेक्ट बनाया गया था तो यह स्वचालित रूप से एक संपत्ति के constructorबराबर दिया गया था Car, इसलिए यह सच है।
अब इसका क्या?
var Animal = new Object();
function Reptile(){ }
Reptile.prototype = Animal;
var lizard = new Reptile();
print(lizard instanceof Reptile);
print(lizard.constructor == Reptile);
यह प्रोग्राम क्या छापता है?
फिर, lizard instanceof Reptileइसका मतलब है " प्रोटोटाइप श्रृंखला Reptile.prototypeपर किसी भी वस्तु के बराबर है lizard?"
हाँ यही है। lizardप्रोटोटाइप है Reptile.prototype, तो हम कर रहे हैं। यह सच छापता है।
अब, किस बारे में
print(lizard.constructor == Reptile);
आप सोच सकते हैं कि यह भी सच है, चूंकि lizardनिर्माण किया गया था , new Reptileलेकिन आप गलत होंगे। कारण बताइए।
- क्या
lizardकोई constructorसंपत्ति है? इसलिए हम प्रोटोटाइप को देखते हैं।
- का प्रोटोटाइप
lizardहै Reptile.prototype, जो है Animal।
- क्या
Animalकोई constructorसंपत्ति है? नहीं, तो हम इसे प्रोटोटाइप के रूप में देखते हैं।
- का प्रोटोटाइप
Animalहै Object.prototype, और Object.prototype.constructorरनटाइम द्वारा बनाया गया है और इसके बराबर है Object।
- इसलिए यह गलत है।
हमें Reptile.prototype.constructor = Reptile;वहाँ किसी बिंदु पर कहना चाहिए था, लेकिन हमें याद नहीं था!
सुनिश्चित करें कि सभी आप के लिए समझ में आता है। यदि यह अभी भी भ्रमित है तो कुछ बक्से और तीर बनाएँ।
दूसरी बेहद भ्रमित करने वाली बात यह है, अगर मैं console.log(Function.prototype)किसी फ़ंक्शन को प्रिंट करता हूं, लेकिन जब मैं प्रिंट console.log(Object.prototype)करता हूं तो वह किसी ऑब्जेक्ट को प्रिंट करता है। Function.prototypeएक समारोह क्यों होता है जब इसे एक वस्तु माना जाता था?
फ़ंक्शन प्रोटोटाइप को एक फ़ंक्शन के रूप में परिभाषित किया जाता है, जिसे जब बुलाया जाता है, तो रिटर्न देता है undefined। हम पहले से ही जानते हैं कि Function.prototypeयह Functionप्रोटोटाइप है, अजीब तरह से पर्याप्त है। इसलिए इसलिए Function.prototype()कानूनी है, और जब आप इसे करते हैं, तो आप undefinedवापस आ जाते हैं। तो यह एक समारोह है।
Objectप्रोटोटाइप इस संपत्ति नहीं है, यह कॉल करने योग्य नहीं है। यह सिर्फ एक वस्तु है।
जब आप console.log(Function.prototype.constructor)इसे फिर से एक समारोह है।
Function.prototype.constructorबस Function, जाहिर है। और Functionएक फंक्शन है।
अब आप इसे स्वयं बनाने के लिए किसी चीज़ का उपयोग कैसे कर सकते हैं (माइंड = ब्लो)।
आप यह सोच रहे हैं । यह आवश्यक है कि रनटाइम वस्तुओं का एक गुच्छा बनाता है जब यह शुरू होता है। ऑब्जेक्ट्स केवल लुकअप टेबल हैं जो ऑब्जेक्ट्स के साथ तार जोड़ते हैं। जब क्रम शुरू होता है, यह सब करना है कुछ दर्जन खाली वस्तुओं को बनाने, और फिर बताए शुरू है prototype, __proto__, constructor, और इतने प्रत्येक वस्तु के गुणों पर जब तक वे ग्राफ है कि वे बनाने की जरूरत है सकते हैं।
यह उपयोगी होगा यदि आप उस आरेख को लेते हैं जो मैंने आपको ऊपर दिया था और constructorइसमें किनारों को जोड़ दिया था। आप जल्दी से देखेंगे कि यह एक बहुत ही सरल ऑब्जेक्ट ग्राफ है और रनटाइम को इसे बनाने में कोई समस्या नहीं होगी।
एक अच्छा व्यायाम इसे स्वयं करना होगा। यहाँ, मैं आपको शुरू करूँगा। हम my__proto__"के प्रोटोटाइप ऑब्जेक्ट" और myprototype"प्रोटोटाइप संपत्ति " का मतलब करने के लिए उपयोग करेंगे ।
var myobjectprototype = new Object();
var myfunctionprototype = new Object();
myfunctionprototype.my__proto__ = myobjectprototype;
var myobject = new Object();
myobject.myprototype = myobjectprototype;
और इसी तरह। क्या आप बाकी प्रोग्राम को ऑब्जेक्ट के एक सेट का निर्माण करने के लिए भर सकते हैं जिसमें "वास्तविक" जावास्क्रिप्ट में निर्मित वस्तुओं के समान टोपोलॉजी है? यदि आप ऐसा करते हैं, तो आप पाएंगे कि यह बेहद आसान है।
जावास्क्रिप्ट में वस्तुएँ सिर्फ लुकअप टेबल हैं जो अन्य वस्तुओं के साथ तार जोड़ती हैं । बस! यहां कोई जादू नहीं है। आप अपने आप को गाँठों में बंधे हुए पा रहे हैं क्योंकि आप उन बाधाओं की कल्पना कर रहे हैं जो वास्तव में मौजूद नहीं हैं, जैसे कि प्रत्येक वस्तु को एक निर्माता द्वारा निर्मित किया जाना था।
फ़ंक्शंस बस एक अतिरिक्त क्षमता वाले ऑब्जेक्ट हैं: जिन्हें बुलाया जाना है। इसलिए अपने छोटे सिमुलेशन कार्यक्रम के माध्यम से जाएं और .mycallableप्रत्येक वस्तु में एक संपत्ति जोड़ें जो इंगित करता है कि यह कॉल करने योग्य है या नहीं। यह इतना सरल है।
Function.prototypeएक फ़ंक्शन हो सकता है और आंतरिक क्षेत्र हो सकते हैं। तो नहीं, जब आप संरचना से गुजर रहे हैं तो प्रोटोटाइप फ़ंक्शन को निष्पादित नहीं करते हैं। अंत में याद रखें कि जावास्क्रिप्ट की व्याख्या करने वाला एक इंजन है, इसलिए ऑब्जेक्ट और फ़ंक्शन संभवतः इंजन के भीतर बनाए जाते हैं और जावास्क्रिप्ट से नहीं और विशेष संदर्भ जैसेFunction.prototypeऔरObject.prototypeबस इंजन द्वारा एक विशेष तरीके से व्याख्या की जा सकती है।