हुह। यह मेरे लिए होने की अपेक्षा अधिक जटिल लग रहा है।
वास्तव में अधिक बारीकी से देखकर मैं सुपरक्लास विधि को कॉल करने के लिए this._super()
प्रदान करने के साथ वास्तव में अपवाद लेता हूं।
कोड typeof==='function'
पर निर्भरता (कुछ वस्तुओं के लिए अविश्वसनीय), Function#toString
(अरे, समारोह अपघटन भी अविश्वसनीय है) परिचय है, और निर्णय लेने से आप समारोह शरीर में बाइट्स _super
के अनुक्रम का उपयोग किया है कि क्या के आधार पर रैप करने के लिए है कि क्या (भले ही आपने इसे केवल एक स्ट्रिंग में उपयोग किया हो। और यदि आप उदाहरण की कोशिश करते हैं। this['_'+'super']
यह असफल हो जाएगा)।
और यदि आप अपने फ़ंक्शन ऑब्जेक्ट्स (जैसे MyClass.myFunction.SOME_PRIVATE_CONSTANT
) पर गुणों को संग्रहीत कर रहे हैं, जो आप नेमस्पेस को साफ रखने के लिए कर सकते हैं) तो रैपिंग आपको उन गुणों को प्राप्त करने से रोक देगा। और यदि किसी विधि में अपवाद फेंक दिया गया है और उसी ऑब्जेक्ट की दूसरी विधि में पकड़ा गया है, तो _super
गलत चीज़ पर इंगित करेगा।
यह सब सिर्फ आपके सुपरक्लास के विधि-समान नाम को कॉल करने के लिए आसान है। लेकिन मुझे नहीं लगता कि जेएस में वैसे भी करना मुश्किल है। यह अपने स्वयं के अच्छे के लिए बहुत चालाक है, और इस प्रक्रिया में पूरी तरह से कम विश्वसनीय है। (ओह, और arguments.callee
सख्त मोड में मान्य नहीं है, हालांकि यह वास्तव में उसकी गलती नहीं है क्योंकि वह इसे पोस्ट करने के बाद हुआ था।)
इस समय कक्षाओं के लिए मैं इसका उपयोग कर रहा हूं। मैं दावा नहीं करता कि यह "सर्वश्रेष्ठ" जेएस क्लास सिस्टम है, क्योंकि लोड करने के विभिन्न तरीकों से लोड होता है और विभिन्न सुविधाओं का एक समूह जो आप जोड़ना या जोड़ना चाहते हैं। लेकिन यह बहुत हल्का है और इसका उद्देश्य 'जावास्क्रिप्टिक' होना है, अगर यह एक शब्द है। (यह नहीं है।)
Function.prototype.makeSubclass= function() {
function Class() {
if (!(this instanceof Class))
throw 'Constructor function requires new operator';
if ('_init' in this)
this._init.apply(this, arguments);
}
if (this!==Object) {
Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
}
return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};
यह प्रदान करता है: आकस्मिक के खिलाफ
सुरक्षा new
गायब है। वैकल्पिक रूप से X()
से new X()
पर चुपचाप रीडायरेक्ट करना है ताकि new
काम न हो। यह एक टॉस-अप है जो सबसे अच्छा है; मैं स्पष्ट त्रुटि के लिए गया ताकि किसी को new
के बिना लिखने के लिए उपयोग न किया जाए और अन्य वस्तुओं पर समस्याएं उत्पन्न न हों। this.
गुणों को window
पर गिरने और रहस्यमय तरीके से गलत होने के बाद अस्वीकार्य जेएस डिफ़ॉल्ट से किसी भी तरह से बेहतर है।
एक विरासत _init
विधि, इसलिए आपको एक कन्स्ट्रक्टर-फ़ंक्शन लिखना नहीं है जो सुपरक्लास कन्स्ट्रक्टर फ़ंक्शन को कॉल करने के अलावा कुछ भी नहीं करता है।
और यह वास्तव में सब कुछ है।
var Person= Object.makeSubclass();
Person.prototype._init= function(isDancing) {
this.dancing= isDancing;
};
Person.prototype.dance= function() {
return this.dancing;
};
var Ninja = Person.makeSubclass();
Ninja.prototype._init= function() {
Person.prototype._init.call(this, false);
};
Ninja.prototype.swingSword= function() {
return true;
};
var p= new Person(true);
p.dance(); // => true
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true
// Should all be true
p instanceof Person &&
n instanceof Ninja && n instanceof Person
सुपर क्लास-बुला विशेष रूप से विधि आप चाहते हैं नामकरण और call
यह अजगर की तरह ing, थोड़ा द्वारा किया जाता है:
यहाँ कैसे आप इसका इस्तेमाल कर सकते हैं Resig के उदाहरण को लागू करने की है। _super
सदस्य को कन्स्ट्रक्टर फ़ंक्शन में जोड़ सकता है यदि आप Person
नामकरण से बचना चाहते हैं (तो आप Ninja._super.prototype._init.call
, या शायद Ninja._base._init.call
कहेंगे)।
मैं जावास्क्रिप्ट देखा है "में उत्पादन "है जो बच्चे के बिल्ली का बच्चा स्वर्गदूतों को रोता है, इसलिए यह वास्तव में आपके यूनिट/पेज परीक्षण पर होने वाले प्रभाव का निर्णय लेने के लिए है। यह एक साधारण बात है कि गंभीर मुद्दों पर लाने की कल्पना करना मुश्किल है। – Pointy
+1 पॉइंट। मैंने अभी नीचे आलोचना की है, लेकिन वास्तव में 99% वेबसाइटों पर उनके बारे में अधिक संदिग्ध कोड है ... – bobince
प्रारंभ के लिए jQuery ... –