जावास्क्रिप्ट में कक्षा कक्षा-आधारित ऑब्जेक्ट मॉडल नहीं है। यह शक्तिशाली प्रोटोटाइपिकल विरासत का उपयोग करता है, जो कक्षाओं की नकल कर सकता है, लेकिन इसके लिए उपयुक्त नहीं है। सबकुछ एक वस्तु है, और वस्तुएं अन्य वस्तुओं से प्राप्त हो सकती हैं।
एक कन्स्ट्रक्टर केवल एक ऐसा कार्य है जो नव निर्मित वस्तुओं को गुण निर्दिष्ट करता है। ऑब्जेक्ट (new
keyword के साथ कॉल द्वारा बनाया गया) this
keyword (जो फ़ंक्शन के लिए स्थानीय है) को संदर्भित किया जा सकता है।
एक विधि भी एक कार्य है जिसे पर एक ऑब्जेक्ट कहा जाता है - फिर ऑब्जेक्ट को इंगित करने के लिए this
के साथ। कम से कम जब उस कार्य को member operator (डॉट, ब्रैकेट) का उपयोग करके ऑब्जेक्ट की संपत्ति के रूप में बुलाया जाता है। इससे नए लोगों के लिए बहुत भ्रम पैदा होता है, क्योंकि यदि आप उस फ़ंक्शन के आसपास गुजरते हैं (उदा। एक ईवेंट श्रोता के लिए) यह उस ऑब्जेक्ट से "अलग" होता है जिस पर इसे एक्सेस किया गया था।
अब विरासत कहां है? एक "वर्ग" के उदाहरण एक ही प्रोटोटाइप ऑब्जेक्ट से प्राप्त होते हैं। विधियों को उस ऑब्जेक्ट पर फ़ंक्शन गुणों के रूप में परिभाषित किया जाता है (प्रत्येक उदाहरण के लिए एक फ़ंक्शन के बजाय), जिस उदाहरण पर आप उन्हें कॉल करते हैं, वह उस संपत्ति को प्राप्त करता है।
उदाहरण:
function Foo() {
this.bar = "foo"; // creating a property on the instance
}
Foo.prototype.foo = 0; // of course you also can define other values to inherit
Foo.prototype.getBar = function() {
// quite useless
return this.bar;
}
var foo = new Foo; // creates an object which inherits from Foo.prototype,
// applies the Foo constructor on it and assigns it to the var
foo.getBar(); // "foo" - the inherited function is applied on the object and
// returns its "bar" property
foo.bar; // "foo" - we could have done this easier.
foo[foo.bar]; // 0 - access the "foo" property, which is inherited
foo.foo = 1; // and now overwrite it by creating an own property of foo
foo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that
(new Foo).foo; // is still 0
तो, हम केवल उस वस्तु के गुणों का उपयोग करें और इसके साथ खुश हैं किया था। लेकिन वे सभी "सार्वजनिक" हैं, और ओवरराइट/बदला/हटाया जा सकता है! यदि इससे कोई फर्क नहीं पड़ता, तो आप भाग्यशाली हैं। आप अंडरस्कोर के साथ अपने नामों का उपसर्ग करके गुणों की "निजीता" को इंगित कर सकते हैं, लेकिन यह केवल अन्य डेवलपर्स के लिए एक संकेत है और इसका पालन नहीं किया जा सकता है (विशेष रूप से त्रुटि में)।
तो, चतुर दिमाग में एक समाधान मिला है जो कि बंदरगाह के रूप में कन्स्ट्रक्टर फ़ंक्शन का उपयोग करता है, जिससे निजी "गुण" बनाने की अनुमति मिलती है। जावास्क्रिप्ट फ़ंक्शन का प्रत्येक निष्पादन स्थानीय चर के लिए एक नया चर वातावरण बनाता है, जो निष्पादन समाप्त होने के बाद एकत्रित कचरा हो सकता है। उस क्षेत्र के भीतर घोषित किए गए प्रत्येक कार्य में इन चरों तक पहुंच होती है, और जब तक उन कार्यों को बुलाया जा सकता है (उदाहरण के लिए एक ईवेंट श्रोता द्वारा) पर्यावरण को जारी रखना चाहिए। तो, आपके कन्स्ट्रक्टर से स्थानीय रूप से परिभाषित कार्यों निर्यात करके आप उस चरणीय वातावरण को स्थानीय चर के साथ संरक्षित करते हैं जिसे केवल इन कार्यों द्वारा एक्सेस किया जा सकता है।
चलो यह कार्रवाई में देखें:
function Foo() {
var bar = "foo"; // a local variable
this.getBar = function getter() {
return bar; // accesses the local variable
}; // the assignment to a property makes it available to outside
}
var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototype
foo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor
यह गेटर समारोह है, जो निर्माता के अंदर परिभाषित किया गया है, अब एक "विशेषाधिकार प्राप्त विधि" यह "निजी" के लिए उपयोग (स्थानीय) के रूप में कहा जाता है "गुण" (चर)। bar
का मान कभी नहीं बदलेगा। आप इसके लिए एक सेटर फ़ंक्शन भी घोषित कर सकते हैं, और इसके साथ आप कुछ सत्यापन आदि जोड़ सकते हैं।
ध्यान दें कि प्रोटोटाइप ऑब्जेक्ट पर विधियों को कन्स्ट्रक्टर के स्थानीय चर तक पहुंच नहीं है, फिर भी वे शायद विशेषाधिकार प्राप्त विधियों का उपयोग करें। आइए एक जोड़ें:
Foo.prototype.getFooBar = function() {
return this.getBar() + "bar"; // access the "getBar" function on "this" instance
}
// the inheritance is dynamic, so we can use it on our existing foo object
foo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix
तो, आप दोनों दृष्टिकोणों को जोड़ सकते हैं। ध्यान दें कि विशेषाधिकार प्राप्त विधियों को अधिक स्मृति की आवश्यकता होती है, क्योंकि आप अलग-अलग स्कोप श्रृंखलाओं (फिर भी वही कोड) के साथ विशिष्ट फ़ंक्शन ऑब्जेक्ट बनाते हैं। यदि आप अविश्वसनीय रूप से बड़ी मात्रा में उदाहरण बनाने जा रहे हैं, तो आपको केवल प्रोटोटाइप पर विधियों को परिभाषित करना चाहिए।
जब आप एक "कक्षा" से दूसरे में विरासत स्थापित कर रहे होते हैं तो यह थोड़ा और जटिल हो जाता है - मूल रूप से आपको बच्चे के प्रोटोटाइप ऑब्जेक्ट को माता-पिता से प्राप्त करना होता है, और बच्चे के उदाहरणों पर मूल निर्माता को लागू करना होता है "निजी गुण"। Correct javascript inheritance, Private variables in inherited prototypes, Define Private field Members and Inheritance in JAVASCRIPT module pattern और How to implement inheritance in JS Revealing prototype pattern?
है 'एक वस्तु संपत्ति .bar' है, एक चर नहीं। तो हाँ, किसी ऑब्जेक्ट से संपत्ति प्राप्त करने के लिए, आपको उस ऑब्जेक्ट के कुछ संदर्भों के माध्यम से ऐसा करने की आवश्यकता है। यदि 'यह 'आपकी वस्तु का संदर्भ देता है, तो' this.bar' आपको वह संपत्ति देगा। –
'this.bar'' bar' जैसा नहीं है। हालांकि आप 'var bar = this.bar' कर सकते हैं जो 'bar' संदर्भ' this.bar' – Loktar
@Loktar बना देगा, लेकिन केवल तभी होगा जब यह'bar.bar' ऑब्जेक्ट या सरणी है ... – Alnitak