2011-06-13 10 views
6

के भीतर ऑब्जेक्ट को अलग करें मैं मुख्य वस्तु रखने का प्रयास कर रहा हूं कि मैं कई उदाहरण बना सकता हूं, जिनमें से प्रत्येक बच्चे को अद्वितीय/अलग गुणों के साथ प्राप्त करता है। जब मैं ऐसा करता हूं, हालांकि, ऑब्जेक्ट के गुण (बदले जाने के बाद) सभी बनाई गई वस्तुओं के लिए बदल रहे हैं। मैं इसे सही ढंग से समझा नहीं सकता, लेकिन उदाहरण बहुत स्पष्ट होना चाहिए। A.foo.bar 2 वापस जाने के लिए और B.foo.bar 3 वापस जाने के लिए के लिएओओपी जावास्क्रिप्ट - कक्षा

Main = function(){}; 

// Extending the main class with new object. Doing it this way so I can have these in 
// separate files. 
Main.prototype.foo = { 
    bar: 1 
} 

// First instance of Main(). 
var A = new Main(); 

// Second instance of Main(). 
var B = new Main(); 

// Set the bar property to different values for each Main() object. 
A.foo.bar = 2; 
B.foo.bar = 3; 

// Both A.foo.bar and B.foo.bar return 3. 
alert(A.foo.bar); 
alert(B.foo.bar); 

क्या मैं ऐसा करने के लिए प्राप्त करने के लिए कोशिश कर रहा हूँ, यह है, ताकि मैं वस्तुओं है कि एक दूसरे से स्वतंत्र हैं अलग-थलग पड़ गए हैं ।

कोई विचार? क्या मुझे बस कुछ याद आ रहा है जो स्पष्ट है? बहुत सराहना की जाएगी!

+1

आपके पास "foo" के लिए दो बार सेटअप क्यों है? क्या यह सिर्फ एक प्रतिलेखन त्रुटि है? – Pointy

उत्तर

5

"foo" संपत्ति प्रोटोटाइप ऑब्जेक्ट पर है, और उनमें से केवल एक ही है। जब आप इसे किसी भी उदाहरण के माध्यम से सेट करते हैं, तो आप उसी साझा संपत्ति को प्रभावित कर रहे हैं।

आप अपने निर्माता में एक उदाहरण संपत्ति जोड़ सकते हैं:

function Main() { 
    this.instanceProperty = 1; 
    } 

तब कि प्रति-उदाहरण हो जाएगा।

प्रोटोटाइप "मास्टर टेम्पलेट" या ऐसा कुछ भी नहीं है; यह एक असली वस्तु है। यह उदाहरणों पर प्रतिलिपि नहीं है। इसके बजाए, रनटाइम जानता है कि यह वहां है, और जब किसी उदाहरण पर गुणों के संदर्भ दिए जाते हैं जो वास्तव में उदाहरण पर मौजूद नहीं होते हैं, तो यह प्रोटोटाइप श्रृंखला को चलने और वहां गुणों को देखने के लिए जानता है।

1

चूंकि आप प्रोटोटाइप पर कुछ संपादित कर रहे हैं, यह हर ऑब्जेक्ट को प्रभावित करेगा।

लेकिन, आप कर सकते हैं:

A.x = 2; 
B.x = 3; 

तो फिर तुम अलग परिणाम होगा।

या, आप कुछ इस तरह हो सकता है:

Main = function(val){ 
    this.x = val; 
} 

A = new Main(2); 
B = new Main(3); 
3

अन्य उत्तर कम या ज्यादा सही हैं, लेकिन क्या वे भूल रहे हैं वहाँ

Main.prototype.foo = { 
    bar: 1 
}; 

और

के बीच एक अंतर है कि है
Main.prototype.bar = 1; 

दोनों मामलों में, एक नया Main तुरंत चालू करने से एक नया निर्माण होगा उदाहरण के साथ, इसकी प्रोटोटाइप श्रृंखला में, एक संपत्ति foo या bar। दोनों ही मामलों में, उदाहरण के स्तर के संपत्ति अन्य उदाहरण को प्रभावित किए बिना नए सिरे से परिभाषित किया जा सकता है:

function Main() {}; 
Main.prototype.foo = { 
    bar: 1 
}; 
Main.prototype.bar = 1; 

a = new Main(); 
b = new Main(); 

a.foo = { bar: 2 }; 
console.log(a.foo.bar, b.foo.bar); // 2 1 

a.bar = 2; 
console.log(a.bar, b.bar); // 2 1 

लेकिन जब आप एक नया Main का दृष्टांत, उदाहरण चर foo एक संदर्भ एक वस्तु, {bar:1} है, जो करने के लिए है सभी मामलों के बीच साझा किया। तो जब आप a.foo.bar सेट करते हैं, तो आप सामान्य ऑब्जेक्ट बदल रहे हैं, उदाहरण आवृत्ति नहीं; आवृत्ति चर संदर्भ a.foo है।

आपको कन्स्ट्रक्टर में इंस्टेंस प्रॉपर्टी प्रारंभ करने की आवश्यकता नहीं है। मानक दृष्टिकोण सीधे प्रोटोटाइप पर bar सेट करना होगा, यानी।Main.prototype.bar = 1, जो आपको 1 पर प्रारंभिक आवृत्ति चर प्रदान करेगा। हालांकि, यदि आपको एक प्रति-उदाहरण आधार पर एक अधिक जटिल डेटा संरचना (एक वस्तु, एक सरणी, या किसी अन्य वर्ग का उदाहरण) की आवश्यकता है, तो आप इसे प्रोटोटाइप पर एक संपत्ति के रूप में नहीं बना सकते हैं, क्योंकि आप होंगे प्रत्येक उदाहरण को एक सामान्य वस्तु का संदर्भ देना - इसलिए कन्स्ट्रक्टर के अंदर जाने का तरीका है:

function Main() { 
    // instance-level object 
    this.foo = { 
     bar: 1 
    }; 
} 
+3

इस उत्कृष्ट पोस्ट को स्पष्ट रूप से समझने के लिए देखें कि प्रोटोटाइप कैसे काम करते हैं: https://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/ – rahulmohan

+0

मुझे लगता है कि कथन "instance variable foo एक ऑब्जेक्ट का संदर्भ है "foo के भीतर एक विशेषता में हेरफेर करने के व्यवहार को समझना महत्वपूर्ण है। – maulik13

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