2013-03-05 6 views
5

नहीं प्रोटोटाइप मैं बहुत प्रोटोटाइप विरासत हासिल करने के लिए शास्त्रीय js तरह से करने के बजाय object.create का उपयोग कर के लिए नया हूँ।Object.create __proto__ की स्थापना लेकिन

var baseObject = { 
test : function(){ 
    console.log('Child'); 
} 
} 

var newObject = Object.create(baseObject); 
newObject.test = function(){ 
console.log('Parent'); 
this.__proto__.test(); 
} 
console.log(newObject); 

newObject.test(); 

का उत्पादन इस (वेब ​​उपकरण में उत्पादन का अनुकरण):

क्रोम में कम से कम मैं निम्नलिखित कोड देख कर हैरान था

Object {test: function, test: function} 
    test: function(){ 
    __proto__: Object 
     test: function(){ 
     __proto__: Object 
Parent 
Child 

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

यहां क्या हो रहा है? मैं object.create "प्रोटोटाइप" स्थापित करेगा बजाय के रूप में है कि मानक है (या तो मैं मान लिया था) लगा। यह पॉपुलटिंग क्यों कर रहा है और मुझे "__proto__"

उत्तर

5

अपने प्रोटोटाइप विरासत को स्थापित करने के लिए __proto__ का उपयोग करके निराश नहीं है क्योंकि यह गैर-मानक है। यही कारण है कि इसका मतलब यह नहीं आप Object.create() उपयोग नहीं कर सकते एक विशेष प्रोटोटाइप वस्तु के साथ एक नई वस्तु बनाने के लिए।

वस्तुओं डिफ़ॉल्ट रूप से एक .prototype संपत्ति नहीं है। आप किसी फ़ंक्शन के .prototype ऑब्जेक्ट को भ्रमित कर रहे हैं।

तो अगर मैं इस तरह एक समारोह है: Foo समारोह वस्तु एक .prototype संपत्ति एक वस्तु है कि जब एक निर्माता के रूप में लागू बनाए गए किसी भी वस्तुओं की __proto__ के रूप में इस्तेमाल किया जाएगा संदर्भ है

function Foo() { 

} 

है।

var f = new Foo(); 

तो अब f अपने प्रोटोटाइप श्रृंखला में Foo.prototype के साथ एक वस्तु है। आप इसे Object.getPrototypeOf() का उपयोग करके सत्यापित कर सकते हैं;

Object.getPrototypeOf(f) === Foo.prototype; // true 

क्या Object.create आप एक ही प्रोटोटाइप श्रृंखला की स्थापना करने की क्षमता है, लेकिन एक निर्माता समारोह का उपयोग किए बिना देता है। तो यह बराबर होगा।

var f2 = Object.create(Foo.prototype); 

अब हम एक उद्देश्य यह है कि मूल f वस्तु के रूप में एक ही तरीके से की स्थापना की है की है।

Object.getPrototypeOf(f2) === Foo.prototype;   // true 
Object.getPrototypeOf(f2) === Object.getPrototypeOf(f); // true 

तो यह सिर्फ क्या अंततः एक ही बात है की एक अलग तरीका है। एक वस्तु और अपने प्रोटोटाइप श्रृंखला के बीच संबंधों को एक आंतरिक रिश्ता है। गैर मानक __proto__ बस उस रिश्ते को उजागर करता है।

+0

बहुत रोचक। आप सही हैं मैं प्रोटोटाइप केवल कार्यों पर लागू भूल गया। तो अनिवार्य रूप से, कम से कम क्रोम, __proto__ प्रकार का उपयोग गैर-मानक तरीके से योजना वस्तुओं के लिए प्रोटोटाइप को दोहराता है? – nahelm

+0

@nahelm: क्रमबद्ध करें। '__proto__' आपको मौजूदा ऑब्जेक्ट को एक नई प्रोटोटाइप श्रृंखला देने देता है। कन्स्ट्रक्टर फ़ंक्शंस और 'ऑब्जेक्ट.क्रेट' बस ऑब्जेक्ट बनने के समय इसे सेट अप करने देते हैं। वहां से यह स्थायी है। वास्तव में, यदि आप कन्स्ट्रक्टर फ़ंक्शन से कोई ऑब्जेक्ट बनाते हैं, तो आप कन्स्ट्रक्टर को एक नया 'प्रोप्रोटाइप' ऑब्जेक्ट देते हैं, जो ऑब्जेक्ट आपने पहले से बनाया है वह अभी भी मूल का संदर्भ देगा। यह कभी नहीं बदलता है। –

+0

मुझे लगता है कि मैं अंततः इसे प्राप्त कर रहा हूं। मेरे भ्रम का एक हिस्सा यह था कि मैंने क्रोम में अपने वेब टूल्स को ऑब्जेक्ट के प्रोटोटाइप को दिखाने के लिए उम्मीद की थी। मैंने कुछ मूर्खतापूर्ण कारणों के बारे में भी सोचा कि नए कीवर्ड का उपयोग करने से आप प्रोटोटाइप कीवर्ड (आपके उदाहरण में f.prototype) का उपयोग कर सकते हैं, जो सत्य नहीं है। जब मैंने आपका फू उदाहरण किया और इसके प्रोटोटाइप में एक फ़ंक्शन जोड़ा, तो यह कंसोल logproto__ ऑब्जेक्ट में भी दिखाई देता है जब मैं console.log (f) करता हूं। इसलिए इस मामले में अनिवार्य रूप से __proto__ प्रोटोटाइप श्रृंखला का खुलासा करता है जो आम तौर पर छिपा हुआ होता है और जैसा कि आपने स्थायी कहा था। – nahelm

0

एक उदाहरण की __proto__ संपत्ति कन्स्ट्रक्टर कीprototype संपत्ति के समान होनी चाहिए।

जब एक वस्तु बन जाता है, इसके __proto__ संपत्ति अपने आंतरिक [[Prototype]] (अर्थात अपने निर्माता के prototype वस्तु) के रूप में एक ही वस्तु को संदर्भित करने के लिए निर्धारित है। __proto__ पर एक नया मान असाइन करने से आंतरिक [[Prototype]] संपत्ति का मूल्य भी बदल जाता है, सिवाय इसके कि ऑब्जेक्ट गैर-एक्स्टेंसिबल कहां है।

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/proto#Description

+0

हालांकि इस मामले में, मूल वस्तु एक वस्तु थी, इसलिए निर्माता का प्रोटोटाइप ऑब्जेक्ट था। नतीजतन 'constructor.prototype! = __proto__'। –

0

Object.create() कि विशेष वस्तु उदाहरण के लिए प्रोटोटाइप सेट। prototype एक कन्स्ट्रक्टर फ़ंक्शन पर एक प्रॉपर्टी है जो कि ऑब्जेक्ट है जो उस रचनाकार फ़ंक्शन के साथ new ऑपरेटर का उपयोग करके बनाए गए प्रत्येक इंस्टेंस के लिए [[प्रोटोटाइप]] के रूप में असाइन किया गया है।

__proto__ किसी विशेष उदाहरण के लिए [[प्रोटोटाइप]] तक पहुंचने का एक गैर-मानक तरीका है। आप प्रोटोटाइप तक पहुंचने के लिए मानक तरीके के लिए Object.getPrototypeOf(this) पर भी कॉल कर सकते हैं।

+1

जब आप आंतरिक संपत्ति के बारे में बात कर रहे हों तो स्पष्ट करने के लिए "प्रोटोटाइप" को [[प्रोटोटाइप]] में बदलना चाहते हैं। –

+0

@MattBall धन्यवाद! – Brandon

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