2012-11-05 11 views
7

मैं एक जावास्क्रिप्ट प्रोजेक्ट पर काम कर रहा हूं, और यह सोच रहा था कि ऑब्जेक्ट उदाहरण defineProperty() और सुपरक्लास (superobject?) Object विधि को कॉल करने के बजाय अन्य विधियों का वारिस क्यों नहीं करता है।इसके बजाय ऑब्जेक्ट.डेफिनप्रॉपर्टी() क्यों है। डिफाईप्रॉपर्टी() (ऑब्जेक्ट्स के लिए)?

मैंनेपर देखा है, और वास्तव में "गैर-मानक" संपत्ति विधियां हैं।

लेकिन उनको बहिष्कृत किया गया है। Object विधियों के लिए कदम क्यों होगा?

ऐसा लगता है कि instance.defineProperty(...)Object.defineProperty(instance, ...) से बेहतर है। मैं कुछ अन्य ऑब्जेक्ट विधियों के बारे में भी यही कहूंगा।

+0

निकट से संबंधित: [क्यों ES5 वस्तु तरीकों नहीं जोड़ा गया था Object.prototype के लिए?] (http: // stackoverflow। कॉम/क्यू/9735026/1048572) – Bergi

उत्तर

7

यह टकराव से बचने के लिए है - सामान्यतः, उन वस्तुओं के साथ समस्याएं जिनके पास आपकी अपेक्षा की जाने वाली कीमत नहीं है।
जेएस में ऑब्जेक्ट्स अक्सर कुंजी-मूल्य-मानचित्र के रूप में उपयोग किए जाते हैं, और चाबियाँ मनमाने ढंग से तार हो सकती हैं - उदाहरण के लिए __defineGetter__, hasOwnProperty या कुछ कम विशेष। अब जब आप किसी अज्ञात ऑब्जेक्ट पर ऐसे फ़ंक्शन का आह्वान करना चाहते हैं - जैसे hasOwnProperty अक्सर सामान्य गणना कार्यों में उपयोग किया जाता है, जहां कोई JSON पारित किया जा सकता है - आप कभी भी यह सुनिश्चित नहीं कर सकते कि क्या आपको ओवरराइट की गई संपत्ति मिली है (जो शायद फ़ंक्शन) या मूल जो आप चाहते हैं, या ऑब्जेक्ट को संपत्ति को विरासत में मिला है या नहीं। इस समस्या से बचने के लिए (या this IE bug), आपको Object.prototype.hasOwnProperty.call का उपयोग करना होगा - वह बदसूरत है।

तो, Object पर उन सभी कार्यों को नामित करना केवल उपयोगी है, यह एक क्लीनर एपीआई है जो प्रतिबिंब विधियों को ऑब्जेक्ट के एप्लिकेशन इंटरफ़ेस से अलग करता है। यह ऑप्टिमाइज़ेशन (स्थिर विश्लेषण को सरल बनाना) में मदद करता है और सैंडबॉक्स में प्रतिबिंब एपीआई तक पहुंच को प्रतिबंधित करना आसान बनाता है - कम से कम design idea

आपको प्रोटोटाइप में defineProperty होने से प्रसन्नता हो सकती है, लेकिन आप ज्ञात वस्तुओं के साथ काम करते समय केवल सुरक्षित रूप से इसका उपयोग कर सकते हैं। आप अभी भी इसे चाहते हैं (जैसा कि आप जब उपयोग करने के लिए जानते हैं और जब नहीं), आप इस्तेमाल कर सकते हैं

Object.defineProperty(Object.prototype, "defineProperty", { 
    writable: true, 
    enumberable: false, 
    value: function(prop, descr) { 
     return Object.defineProperty(this, prop, descr); 
    } 
}); 
+7

यह ध्यान देने योग्य भी है कि वस्तुओं को ES5 में 'ऑब्जेक्ट.प्रोटोटाइप' से प्राप्त करने की आवश्यकता नहीं है। वे 'ऑब्जेक्ट.क्रेट (शून्य)' के माध्यम से कुछ भी नहीं प्राप्त कर सकते हैं, या वे किसी ऑब्जेक्ट से प्राप्त कर सकते हैं जो 'शून्य' से प्राप्त होता है। यह बहुत उपयोगी व्यवहार है, लेकिन यदि कोई ऑब्जेक्ट 'ऑब्जेक्ट.प्रोटोटाइप' से प्राप्त नहीं होता है, तो इसमें 'ऑब्जेक्ट.प्रोटोटाइप' पर परिभाषित विधियां नहीं होंगी।किसी भी लाइब्रेरी को 'defineProperty' का उपयोग करना चाहते हैं, सामान्य रूप से' var defineProperty = Function.prototype.call.bind (Object.prototype.defineProperty) करना होगा; ', इसलिए यह केवल एक उपयोगिता फ़ंक्शन के रूप में इसे परिभाषित करने के लिए समझ में आता है तरीका। –

+1

@ नाथन: बहुत अच्छे अंक, धन्यवाद। – Bergi

+0

दरअसल, असली कारण सैंडबॉक्सिंग और एक बेहतर एपीआई के लिए है - मैं इसे साबित कर सकता हूं लेकिन "rationale_for_es3_1_static_object_methodsaug26.pdf" मर चुका है। –

2

दिलचस्प। अब तक का एकमात्र कारण यह है कि लोग प्रोटोटाइप को फिर से लिखना पसंद करते हैं और इस तरह की "छुपी" इस विधि से आपको कुछ कीड़े से बचने में मदद मिल सकती है। खासतौर से अच्छे विधि के नाम के कारण, क्योंकि इससे अधिक लिखा जा सकता है, उदाहरण के लिए, __defineGetter__

ऐसा लगता है कि बहुत सी विशेषताएं इस कार्यक्षमता (link) पर निर्भर करती हैं, इसलिए इस संदर्भ में इसे और अधिक वैश्विक और सुरक्षित बनाने के लिए यह समझ में आता है।

2

यह टकराव से बचने के लिए ऐसा किया जाता है - याद रखें, Object.prototype पर हर विधि प्रत्येक उपयोगकर्ता द्वारा परिभाषित वस्तु में भी एक विधि है।

ऐसी वस्तु की कल्पना करें जहां आप एक कस्टम विधि defineProperty चाहते हैं - जो Object.defineProperty इसके प्रोटोटाइप पर पूरी तरह से चीजों को तोड़ देगा।

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

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