जावास्क्रिप्ट एक OOP प्रोटोटाइप और नहीं वर्गों के आधार पर भाषा है। यह उन सभी भ्रमों में से एक है जो आप आसपास देख सकते हैं: बहुत से डेवलपर जेएस का उपयोग करते हैं क्योंकि यह कक्षा-आधारित था।
इसलिए, आप कई पुस्तकालयों को देख सकते हैं जो जेएस में कक्षा-आधारित भाषा के प्रतिमान का उपयोग करने का प्रयास कर रहे हैं।
इसके अतिरिक्त, जेएस में कुछ लक्षणों की कमी है जो विरासत, प्रोटोटाइप-आधारित, दर्दनाक बनाता है। उदाहरण के लिए, Object.create
से पहले किसी अन्य ऑब्जेक्ट से ऑब्जेक्ट बनाने का कोई तरीका नहीं था (जैसे ओओपी प्रोटोटाइप-आधारित भाषा करना चाहिए), लेकिन केवल function
का उपयोग कन्स्ट्रक्टर के रूप में करना है।
और इसी कारण से, आप कई पुस्तकालयों को देख सकते हैं जो भाषा को "ठीक करने" की कोशिश कर रहे हैं, हर कोई अपने तरीके से।
तो, आपका भ्रम सामान्य है। मान लें कि, "आधिकारिक" तरीका prototype
संपत्ति, function
एस कन्स्ट्रक्टर के रूप में उपयोग किया जाता है, और Object.create
ऑब्जेक्ट के इंस्टेंस से बनाने के लिए उपयोग किया जाता है। हालांकि, जैसा ऊपर बताया गया है, कुछ मामलों में कोड वर्बोज़ है या इसमें कार्यक्षमता की कमी है, इसलिए इस प्रक्रिया को अक्सर किसी तरह से लपेटा जाता है, और फिर यह व्यक्तिगत स्वाद का विषय बन जाता है।
क्योंकि आप मॉडल के बारे में बात कर रहे हैं, तो आप Backbone's Model पर एक नज़र डाल सकते हैं और देख सकते हैं कि यह दृष्टिकोण आपको फिट करता है या नहीं।
अद्यतन:
function Model() {
this.foo = "foo";
this.array = [];
}
Model.prototype.foo = "";
Model.prototype.array = null;
Model.prototype.doNothing = function() {};
function RestModel() {
this.bar = "bar";
}
RestModel.prototype = new Model;
RestModel.prototype.bar = ""
var myModel = new RestModel();
अब, यहाँ मुद्दों:
- निर्माता कुछ उदाहरण मुझे आशा है कि आपकी मदद करता है स्पष्ट करने के लिए, यहाँ पुराने स्कूल विरासत रास्ता
new
का उपयोग कर देने के लिए Model
को एक बार कहा जाता है, केवल तभी जब RestModel.prototype
सेट किया गया है। इसलिए, प्रत्येक RestModel
उदाहरण के लिए foo
संपत्ति "foo" होगी।
- न केवल वह, लेकिन सभी
RestModel
उदाहरण this.array
संपत्ति में एक ही सरणी का एक ही उदाहरण साझा करेंगे। यदि आप सीधे Model
का उदाहरण बनाते हैं, तो आपके पास प्रत्येक उदाहरण के लिए सरणी का एक नया उदाहरण है।
myModel.constructor
के बजाय Model
है। ऐसा इसलिए है क्योंकि हम को Model
के नए उदाहरण के साथ ओवरराइड करते हैं, जिसमें constructor
Model
के बराबर है।
- यदि आप
RestModel
का नया उदाहरण कन्स्ट्रक्टर को आलसी कॉल के साथ रखना चाहते हैं, तो संभव नहीं है।
मुझे लगता है कि मुख्य बिंदु हैं, बेशक वे केवल एकमात्र नहीं हैं। तो, उन मुद्दों को कैसे हल करें? जैसा कि मैंने कहा, बहुत से लोग पहले से ही ऐसा कर चुके हैं, और वे शब्दशः को सीमित करने के लिए पुस्तकालय और ढांचे को भी बनाते हैं। हालांकि, एक विचार है करने के लिए:
function Model() {
this.foo = "foo";
this.array = [];
}
Model.prototype.foo = "";
Model.prototype.array = null;
Model.prototype.doNothing = function() {};
function RestModel() {
Model.call(this);
this.bar = "bar";
}
RestModel.prototype = Object.create(Model.prototype);
RestModel.prototype.constructor = RestModel;
RestModel.prototype.bar = ""
var myModel = new RestModel();
// for lazy constructor call
var anotherModel = Object.create(RestModel.prototype);
RestModel.call(anotherModel);
सूचना आप ऐसा कर सकते आप prototype
या function
निर्माता के रूप में उपयोग करने के लिए, Object.create
साथ नहीं करना चाहते हैं कि:
var Model = {
foo: "",
array: null,
doNothing: function() {}
}
var RestModel = Object.create(Model);
RestModel.bar = "";
var myModel = Object.create(RestModel);
// Assuming you have to set some default values
initialize(RestModel);
या:
var Model = {
foo: "",
array: null,
doNothing: function() {},
init : function() {
this.foo = "foo";
this.array = [];
},
}
var RestModel = Object.create(Model);
RestModel.bar = "";
RestModel.init = function() {
Model.init.call(this);
this.bar = "bar";
}
var myModel = Object.create(RestModel);
myModel.init();
उस स्थिति में आप मूल रूप से निर्माता का नकल करते हैं। आप descriptor
से Object.create
(docs देखें) को भी पास कर सकते हैं लेकिन यह अधिक वर्बोज़ बन जाता है। अधिकांश लोग extend
फ़ंक्शन या विधि का उपयोग करते हैं (जैसा कि आपने शायद बैकबोन उदाहरण में देखा है)।
उम्मीद है कि यह मदद करता है!
उस मामले में 'ऑब्जेक्ट। क्रेते' बेहतर क्यों है? अगर मैं कन्स्ट्रक्टर का भी समर्थन करना चाहता हूं तो क्या होगा? और यह कि कन्स्ट्रक्टर को 'रेस्टमोडेल' और 'मॉडल' दोनों में बुलाया जाता है (यदि मैं 'रेस्टमोडेल' बना देता हूं)। मैं आमतौर पर एक सी # देव हूं, इसलिए मुझे वास्तव में अंतर नहीं मिलता है। मैं बेस प्रोटोटाइप को परिभाषित करना चाहता हूं और एक कन्स्ट्रक्टर का उपयोग करना चाहता हूं, लेकिन मुझे समझ में नहीं आता कि मैं दोनों कैसे प्राप्त करता हूं? – jgauffin
मुझे लगता है कि यह उत्तर * "उचित क्या है इसका उपयोग करें" के साथ यह बताता है। * कभी-कभी आप कन्स्ट्रक्टर में तर्क चाहते हैं, कभी-कभी नहीं। +1 –