पहले जोड़े पैराग्राफ वर्णन करते हैं कि मैं क्या हासिल करने का प्रयास कर रहा हूं, वास्तविक प्रश्न अंत में है। धन्यवादऑब्जेक्ट-निर्माण फ़ंक्शन
पहले, मैं ऑब्जेक्ट बनाने के लिए new
कीवर्ड का उपयोग कर रहा हूं, और विधियों को असाइन करने और विरासत को संभालने के लिए प्रोटोटाइप का उपयोग कर रहा हूं। हाल ही में, तथापि, (आंशिक रूप से CoffeeScript-उत्पन्न जे एस से प्रेरित) मैं एक वस्तु बनाने समारोह के साथ खेलने के लिए है कि कुछ इस तरह दिखाई होगा फैसला:
var Test = function(a) {
function Test(a) {
this.a = a;
}
var numCalls = 0;
Test.prototype.output = function() {
alert('I was initialized with ' + this.a);
numCalls++;
};
Test.prototype.called = function() {
alert('You called the output ' + numCalls + ' times');
};
return new Test(a);
};
मैं तो इस तरह की एक नई वस्तु बनाने होगा:
var obj = Test('string');
इस दृष्टिकोण के सामान्य दृष्टिकोण पर कुछ फायदे हैं जो प्रत्येक उदाहरण के लिए new
का उपयोग करते हैं। सबसे पहले, मुझे new
शब्द का उपयोग करना भूलने की बहुत कम संभावना है (मुझे पता है कि new
से बचने के अन्य तरीके हैं, लेकिन मैंने जो देखा है उससे उन्हें नीचे वर्णित एक की समस्या है), और दूसरा, मैं आसानी से कर सकता हूं 'निजी' वेरिएबल देखें जो कन्स्ट्रक्टर किसी भी फ़ंक्शन में देखता है जो अब कक्षा का हिस्सा है। हालांकि परीक्षण करते समय मैंने एक चेतावनी में भाग लिया था। instanceof
अब काम नहीं करता है क्योंकि यह आंतरिक-स्कोप्ड ऑब्जेक्ट टेस्ट नहीं देखता है। इसके आसपास काम करने के लिए, मैंने इसके बजाय कन्स्ट्रक्टर प्रॉपर्टी का उपयोग करने की कोशिश की:
var a = Test('one');
var b = Test('two');
a.constructor == b.constructor // false
a.constructor.name == b.constructor.name // true
और यही मुझे उलझन में मिला। ऑब्जेक्ट-निर्माण फ़ंक्शन का उपयोग किये बिना वही ऑब्जेक्ट्स बनाना उनके कन्स्ट्रक्टर को बराबर बना देगा, लेकिन इस मामले में वे भिन्न हैं। मेरा अनुमान है कि क्या हो रहा है कि फ़ंक्शन चलाने पर हर बार एक नया ऑब्जेक्ट प्रकार उत्पन्न होता है (ऑब्जेक्ट संरचना समान होती है, लेकिन प्रोटोटाइप का उदाहरण अलग होता है)।
यदि समस्या की मेरी समझ सही है, तो इसका मतलब यह भी है कि कोड मेरे जावास्क्रिप्ट को प्रति क्रिया उदाहरण के लिए अतिरिक्त मेमोरी आवंटित कर रहा है जो कि उदाहरण के बीच साझा किया जाना चाहिए ताकि प्रत्येक उदाहरण के लिए एक समान ऑब्जेक्ट प्रोटोटाइप बनाया जा सके। (प्रोटोटाइप का उपयोग करने के पूरे उद्देश्य को हराकर)? यदि हां, तो क्या इस पैटर्न के लाभों को ध्यान में रखते हुए (आंतरिक कार्यों के बीच निजी चर साझा करने की क्षमता और new
कीवर्ड का उपयोग न करने के दौरान) इस से बचने का कोई अच्छा तरीका है?
यदि मैं समस्या को गलत समझ रहा हूं, तो क्या कोई मुझे वास्तव में क्या हो रहा है पर प्रकाश डाल सकता है?
आप कीवर्ड को नया क्यों भूल जाते हैं? मेरा मतलब है, हर बार जब आप एक नई वस्तु बनाते हैं, तो आप "नया" उपयोग करते हैं, यह बहुत आसान है। यह समाधान कई ओओ भाषाओं में दर्जनों वर्षों के लिए मौजूद है, और यह एक अच्छी बात है, क्योंकि हर कोई आपके कोड को पढ़ और समझ सकता है। जबकि कोई भी var obj = test ('string') को समझता नहीं है, आपका कोड कम पठनीय होगा। लेकिन यह कुछ जेएस प्रोग्रामर का अंतिम लक्ष्य है, मुझे पता है। ;) – Marcus
@ मार्कस, जैसा कि बताया गया है, 'नया' कीवर्ड इस पैटर्न का एकमात्र लाभ नहीं है। इसके अलावा, मैं टीम पर एकमात्र प्रोग्रामर नहीं हूं। यह मानते हुए कि हर कोई हमेशा 'नए' कीवर्ड का उपयोग करना याद रखेगा, जबकि पायथन में बैक-एंड लिखना (जो वर्गों के लिए 'नया' उपयोग नहीं करता है) अवास्तविक है। प्रत्येक उदाहरण निर्माण की तुलना में कक्षा घोषणा के अंत में एक लापता 'नया' खोजना बहुत आसान है। –
आह, मुझे अब मिल गया: प्रोग्रामर को यह कहने वाला कोई कंपाइलर नहीं है कि वह "नया" भूल गया, इसलिए आप इसका उपयोग नहीं करना चाहते हैं। – Marcus