2012-04-26 13 views
10
var someObj = function() { } 
var p = new someObj(); 

alert(someObj.prototype); // This works 
alert(p.prototype);   // UNDEFINED, but why? 

someObj.prototype.model= "Nissan"; 
alert(p.model);    // This works! I understand the dynamic nature of prototypes, but doesn't that mean that p.prototype === someObj.prototype? 

ऐसा क्यों है? चूंकि "पी" "कुछ ओबीजे" का एक उदाहरण है, प्रोटोटाइप क्यों अनिश्चित है? मेरा मतलब है, जब मैं "कुछ ओबीजे" प्रोटोटाइप में एक संपत्ति जोड़ता हूं, तो यह "पी" तक पहुंच योग्य है, तो प्रोटोटाइप क्यों उपलब्ध नहीं है?ऑब्जेक्ट.क्रेट के माध्यम से जावास्क्रिप्ट प्रोटोटाइप()

उत्तर

11

यहां महत्वपूर्ण बात यह है कि prototype फ़ंक्शन ऑब्जेक्ट्स की संपत्ति किसी ऑब्जेक्ट का प्रोटोटाइप नहीं है। यह ऑब्जेक्ट है जिसे आप new someObj के माध्यम से बनाए गए ऑब्जेक्ट के प्रोटोटाइप के रूप में असाइन किया जाएगा। ES5 से पहले, आप सीधे किसी ऑब्जेक्ट के प्रोटोटाइप तक नहीं पहुंच सकते हैं; ईएस 5 के रूप में, आप Object.getPrototypeOf के माध्यम से कर सकते हैं।

पुन

alert(p.prototype); // UNDEFINED, but why?

कारण यह है कि p वस्तु एक संपत्ति "प्रोटोटाइप" कहा जाता है नहीं है। इसमें अंतर्निहित प्रोटोटाइप है, लेकिन ऐसा नहीं है कि आप इसे कैसे एक्सेस करते हैं।

सभी फ़ंक्शन ऑब्जेक्ट्स में prototype नामक एक संपत्ति होती है ताकि अगर उन्हें कन्स्ट्रक्टर फ़ंक्शंस के रूप में उपयोग किया जाता है, तो हम परिभाषित कर सकते हैं कि उन रचनाकारों द्वारा बनाई गई वस्तुओं के अंतर्निहित प्रोटोटाइप के गुण क्या होंगे। यह आपकी मदद कर सकते हैं: अंतिम पंक्ति इस तरह काम करता है

function Foo() { 
} 
Foo.prototype.answer = 42; 

console.log(Foo.prototype.answer); // "42" 
var f = new Foo(); 
console.log(f.answer); // "42" 

कि:

  1. f वस्तु प्राप्त करें।
  2. f है अपने संपत्ति "उत्तर" कहा जाता है?
  3. नहीं, f एक प्रोटोटाइप है?
  4. हां, क्या प्रोटोटाइप में है संपत्ति "उत्तर" कहलाती है?
  5. हां, उस संपत्ति का मूल्य वापस करें।

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

+0

उत्कृष्ट स्पष्टीकरण –

+0

@ टाहा अहमद: खुशी हुई जिसने मदद की! –

2

पी.प्रोटोटाइप काम नहीं करता है क्योंकि इस मामले में p = someObj.prototype।

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

इस प्रकार पी = someObj.prototype और p.prototype को परिभाषित नहीं किया गया है क्योंकि पी एक निर्माता नहीं है।

यह लेख मदद कर सकता है बताते हैं इस अधिक

http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=A2ikc3JLxeD

+0

प्रति क्रॉउडर के उत्तर, ऑब्जेक्ट .getPrototypeOf (पी) के उपयोग के माध्यम से प्रोटोटाइप वहाँ है और सुलभ है। अगर मेरी समझ सही है, तो गुणों और विधियों को वस्तुओं के नए उदाहरणों में कॉपी किया जाता है, लेकिन इसका मतलब यह नहीं है कि p === someObj.prototype। इसका मतलब है p.prototype === someObj.prototype –

1

p एक उदाहरण someObj की है। प्रोटोटाइप कन्स्ट्रक्टर से संबंधित है।

6

का उपयोग कर p के कन्स्ट्रक्टर प्रोटोटाइप को पुनर्प्राप्त कर सकते हैं क्योंकि prototype कन्स्ट्रक्टर फ़ंक्शन की एक संपत्ति है, न कि स्वयं की संपत्ति। हालांकि, prototype वस्तु निर्माता के लिए एक संदर्भ है, तो आप उपयोग कर सकते हैं अपने constructor संपत्ति के माध्यम से एक वस्तु की prototype:

function Foo() {} 

Foo.prototype.foo = "bar"; 

var c = new Foo; 

console.log(c.constructor === Foo); // true 
console.log(c.constructor.prototype); // { foo: 'bar' } 

बहरहाल, यह अगर आप निर्माता समारोह के प्रारंभिक prototype संपत्ति के ऊपर लिख काम नहीं करेगा:

function Foo() {} 

// I overwrite the prototype property, so I lose the initial reference 
// to the constructor. 
Foo.prototype = { 
    foo: "bar" 
}; 

var c = new Foo; 

console.log(c.constructor === Foo); // false 
console.log(c.constructor === Object); // true 
console.log(c.constructor.prototype); // {} 

यही कारण है कि आप ईएस 5 में पेश की गई नई Object.getPrototypeOf विधि का उपयोग बंद कर रहे हैं।

function Foo() {} 

Foo.prototype = { 
    foo: "bar" 
}; 

var c = new Foo; 

console.log(c.constructor === Foo); // false 
console.log(c.constructor === Object); // true 
console.log(c.constructor.prototype); // {} 
console.log(Object.getPrototypeOf(c)); // { foo: 'bar' } 

एक अन्य समाधान सुनिश्चित करें कि आप प्रोटोटाइप पर constructor संदर्भ बहाल करने के लिए हो गया होता:

function Foo() {} 

// Overwriting the initial prototype  
Foo.prototype = { 
    constructor: Foo, // restore the constructor reference 
    foo: "bar" 
}; 
+0

मुझे एक बेहद उपयोगी ब्लॉगपोस्ट मिला, जो इस उत्तर के साथ गठबंधन करता है, पूरे प्रोटोटाइप पागलपन के बारे में बहुत भ्रम को साफ़ करता है। http://blog.sklambert.com/javascript-prototype/ आरेख इस उत्तर को समझने में बहुत मदद करता है। उम्मीद है कि यह किसी की मदद करता है। – Bruce

0

जावास्क्रिप्ट में, निर्माताओं, और वास्तव में सभी कार्यों एक प्रोटोटाइप संपत्ति मिलता है। एक ऑब्जेक्ट (यानी, कुंजी-मूल्य जोड़े का एक सेट) में प्रोटोटाइप प्रॉपर्टी नहीं है। ऊपर अपने उदाहरण,

var someObj = function() { } // this is a function, so it has a prototype property 
var p = new someObj(); // this is an instance object, so it doesn't 

क्यों someObj.prototype परिभाषित किया जाता है यही कारण है, लेकिन p.prototype नहीं है में।

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