2011-10-20 29 views
6

JavaScript स्निपेट के लिए निम्न पर विचार करें:विरासत का उपयोग करते समय कन्स्ट्रक्टर फ़ंक्शन और प्रोटोटाइप ऑब्जेक्ट के बीच कोई अंतर है?

function baz() { 
} 

baz.prototype = new foo(); 

दोनों ही मामलों में baz एक सदस्य bar लेकिन होने समाप्त होता है क्या अंतर है:

function foo() { 
    this.bar = function() { }; 
} 

// or... (if we used an empty constructor function) 

foo.prototype.bar = function() { }; 

क्या फर्क जब मैं यह कर रहा है? मैं इसे विभिन्न स्थानों पर क्यों करूं?

उत्तर

10

अंतर है जहां प्रोटोटाइप श्रृंखला में संपत्ति स्थित है।

मान लें कि हमारे पास f = new foo(); और b = new baz() है।

foo की परिभाषा एक प्रोटोटाइप का उपयोग किए बिना:

+-----------+  +---------------+ 
|  f  |  | foo.prototype | 
| __proto__-+---->| constructor | 
| bar  |  |    | 
+-----------+  +---------------+ 

bar वस्तु ही (f.howOwnProperty('bar') रिटर्न true) की संपत्ति है तो हम निम्न स्थितियों की है।

आप के बजाय प्रोटोटाइप करने के लिए संपत्ति असाइन करते हैं, स्थिति यह है:

+-----------+  +---------------+ 
|  f  |  | foo.prototype | 
| __proto__-+---->| constructor | 
|   |  | bar   | 
+-----------+  +---------------+ 

f अपनी ही संपत्ति bar नहीं है, लेकिन संपत्ति अन्य सभी foo उदाहरणों के साथ साझा है।

दूसरा टुकड़ा, जिसमें या तो परिणाम के लिए इसी तरह

+-----------+  +---------------+  +---------------+ 
|  b  |  | foo instance |  | foo.prototype | 
| __proto__-+---->| __proto__ -+---->| constructor | 
|   |  | bar   |  |    | 
+-----------+  +---------------+  +---------------+ 

या

+-----------+  +---------------+  +---------------+ 
|  b  |  | foo instance |  | foo.prototype | 
| __proto__-+---->| __proto__ -+---->| constructor | 
|   |  |    |  | bar   | 
+-----------+  +---------------+  +---------------+ 

क्यों आप ऐसा करना चाहते हैं?

यह मुख्य रूप से संरचना के बारे में है और स्मृति को बर्बाद नहीं कर रहा है। आप एक निर्माता समारोह में एक वस्तु के लिए काम करता है जोड़ सकते हैं:

function Foo() { 
    this.bar = function() {}; 
} 

लेकिन यह भी मतलब है कि Foo के प्रत्येक उदाहरण अपने आप कार्य है, कि है, f1.bar === f2.barfalse है, हालांकि दोनों कार्यों सटीक एक ही बात कर रहे हैं।

प्रोटोटाइप का उपयोग करके आप सभी उदाहरणों और उदाहरण-विशिष्ट लोगों के लिए सामान्य गुणों को अलग करने का एक साफ तरीका प्रदान करते हैं।

अंत में, यह "बस" विरासत है जो सॉफ़्टवेयर विकास (एकत्रीकरण) में एक अवधारणा है और इसका उपयोग कहीं भी किया जा सकता है। आपका दूसरा स्निपेट मूल रूप से इसका मतलब है कि bazis-afoo है, इसलिए baz उदाहरण, इसके गुणों के अतिरिक्त, foo उदाहरण (विरासत) के समान गुण हैं।

+1

+1 स्पष्टीकरण पर मेरे प्रयास से काफी बेहतर :) –

-1

मुझे लगता है कि मैं यहां सही सवाल का जवाब दे रहा हूं, अन्यथा मुझे बताएं।

अंतर यह है कि प्रोटोटाइप परिणामों का उपयोग केवल 1 उदाहरण में किया जाता है।

तो, उदाहरण के लिए, एक उदाहरण में baz.bar दूसरे में baz.bar जैसा ही है। वे 'foo' उदाहरण के भीतर मूल्यों को साझा करेंगे: सीधे 'foo' को कॉल कर रहे थे, तो वे foo भीतर मूल्यों को साझा नहीं किया जाएगा

function foo() { 
    var x = 0; 
    this.bar = function() {}; 

    this.getVal = function() { 
     return x; 
    } 

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

function baz() {} 

baz.prototype = new foo(); 

var a = new baz(), 
    b = new baz(); 

a.setVal("1234") 
console.log(b.getVal()); // prints '1234' 

http://jsfiddle.net/jonathon/7GtRD/

a हैं और b। हालांकि, यह वह जगह है जहां यह this.bar सेट करने और बार बनाने के लिए प्रोटोटाइप का उपयोग करने के बीच थोड़ा अलग है।

प्रोटोटाइप का उपयोग bar का एक उदाहरण बना देगा। तो a.barb.bar जैसा ही होगा। यदि आप इसे दूसरी तरफ करते हैं, तो वे दो अलग-अलग कार्य होंगे (एक ही काम कर रहे हैं)।

0

मौजूदा जवाब पर जोड़ने के लिए:

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

function foo(){} 
foo.prototype.bar = function(){return 1}; 
function baz(){} 
baz.prototype = new foo(); 
new baz().bar(); //returns 1 
foo.prototype.bar = function(){return 2}; 
new baz().bar(); //returns 2 

हालांकि, निर्माता में डालने अन्य वस्तुओं यह से इनहेरिट भी "है" कि समारोह जोड़ सकेगा, लेकिन समारोह विरासत में मिला नहीं है।

function foo(){this.bar = function(){return 1};} 
function baz(){} 
baz.prototype = new foo(); 
new baz().bar(); //returns 1 
foo.prototype.bar = function(){return 2}; 
new baz().bar(); //returns 1 
+0

तो उदाहरण 2 में, यह किसी ऑब्जेक्ट के संरक्षित फ़ंक्शन की तरह व्यवहार करता है। क्या यह व्यवहार हम नहीं चाहते हैं? यह अन्य सभी प्रोग्रामिंग भाषाओं की तरह है ... –

1

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

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

function myFunction() {} 

function foo() { 
    this.bar = myFunction; 
} 

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

+0

सच है, हालांकि प्रोटोटाइप का उपयोग करते समय भी, किसी उदाहरण में अन्य उदाहरणों को प्रभावित किए बिना अपनी 'बार' संपत्ति हो सकती है। –

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