2013-02-20 29 views
39

संख्यात्मकता संपत्ति के तीन गुणों में से एक है: उत्तरदायित्व, गणना, और कॉन्फ़िगरेशन। मेरे प्रश्न हैं:संपत्तियों को गैर-गणना करने के क्या फायदे हैं?

  • जावास्क्रिप्ट में गुणों को गैर-गणना करने का क्या फायदा है? मुझे पता है कि हम उन्हें गैर-गणित बनाकर संपत्ति छुपा रहे हैं, लेकिन संपत्ति छिपाने का क्या फायदा है?
  • क्या हम गैर-संख्यात्मक गुणों तक पहुंच सकते हैं? यदि हां, तो उन्हें गैर-गणना करने का क्या फायदा है?
  • ऑब्जेक्ट्स के सभी पूर्वनिर्धारित गुण गैर-गणना के रूप में सेट हैं? जैसे कि ऐरे के pop और push गुणों का मामला गैर-गणनीय है?
+1

मुझे लगता है कि मुख्य लाभ बनाने के लिए 'in' के लिए सुरक्षित लूप है - संपत्ति दिखाई नहीं देंगे जब वस्तु पर पुनरावृत्ति। हो सकता है कि मैं भूल रहा हूं कि कौन सी संख्यात्मकता है ... – Ian

+2

संबंधित: [जावास्क्रिप्ट में ऑब्जेक्ट.प्रोटोटाइप में विधियों को जोड़ने के लाभ और खतरे क्या हैं?] (Http://stackoverflow.com/questions/3832617/what-are-the -benefits और खतरों के- जोड़ने-तरीकों करने वाली वस्तु प्रोटोटाइप में Javas? RQ = 1)। –

उत्तर

35

मुझे लगता है कि मुख्य लाभ सक्षम होने के लिए है नहीं कर रहे हैं ऑब्जेक्ट की गुणों की गणना करते समय क्या दिखाता है, जैसे for in या Object.keys()

MDN यह अच्छी तरह से बताते हैं Object.defineProperty साथ: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty

तो सामान्य रूप से, जब लोग इस तरह के कुछ विधि के लिए एक polyfill वर्ष ब्राउज़र में समर्थित नहीं के रूप में Object के लिए एक विधि को जोड़ने के लिए, चाहते हैं, वे .prototype संशोधित करते हैं। लेकिन यह संपत्ति को ग़लत बनाता है और .hasOwnProperty का उपयोग किये बिना लूप/चाबियाँ संग्रह () में वापस लौटाया जाता है ... जो हर कोई उपयोग नहीं करता है)।

की तरह कुछ के बजाय:

Object.prototype.myMethod = function() { 
    alert("Ahh"); 
}; 

आप Object.defineProperty का उपयोग स्पष्ट रूप से कहने के लिए कर सकता है के लिए यह गणनीय नहीं हो:

Object.defineProperty(Object.prototype, 'myMethod', { 
    value: function() { 
     alert("Ahh"); 
    }, 
    enumerable: false 
}); 

इस प्रकार, उदाहरण के लिए आप for (var key in obj) उपयोग करते हैं, "MyMethod "एक आइटम समझा नहीं जाएगा, और आपको .hasOwnProperty का उपयोग करने की चिंता करने की आवश्यकता नहीं होगी। इसके साथ मुख्य समस्या यह है कि कुछ ब्राउज़र निश्चित रूप से इसका समर्थन नहीं करते हैं: http://kangax.github.com/es5-compat-table/ और यह कि सभी पुस्तकालय/कोड इसका उपयोग नहीं करते हैं, इसलिए आप हमेशा सही और हर समय उपयोग करने के लिए बाहरी पुस्तकालयों/कोड पर भरोसा नहीं कर सकते हैं।

आप किसी भी समय एक गैर-गणना योग्य संपत्ति तक पहुंच सकते हैं, यह वस्तु के गुणों की गणना करते समय दिखाई नहीं देगा - यह मुख्य बिंदु है।

और मुझे विश्वास है कि वस्तुओं की सभी "पूर्वनिर्धारित" गुण गैर-गणना योग्य हैं। इसके द्वारा, मैं वास्तव में केवल मूल गुणों का मतलब है, जरूरी नहीं कि विरासत में बनाया गया हो या बनाया गया हो। तो आपके उदाहरण के साथ, pop और push पर गणना नहीं की जाएगी, लेकिन Array.prototype.indexOf यदि यह पुराने ब्राउज़र पर एक पॉलीफिल के रूप में बनाया गया है जो उस विधि का समर्थन नहीं करता है ...निश्चित रूप से, ऊपर दिए गए मेरे उदाहरण की तरह Object.defineProperty का उपयोग करके बचा जा सकता है। एक और उदाहरण length संपत्ति है, जिस पर गणना नहीं की गई है। http://jsfiddle.net/aHJ3g/

का उपयोग करें और Object.keys की परिभाषा महत्वपूर्ण है:: "एक दिया वस्तु की अपनी गणनीय गुण की एक सरणी अंतर देता है, एक for-in पाश द्वारा प्रदान की किसी एक ही क्रम में (

यहाँ सामान्य रूप में एक उदाहरण है यह कि for-in लूप प्रोटोटाइप श्रृंखला में गुणों को भी समझाता है)। " - एमडीएन से - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

2
  • आप अभी भी इसे उपयोग कर सकते हैं संपत्ति गैर गणनीय करके। लेकिन जब आप ऑब्जेक्ट पर लूप में एक के लिए आवेदन करते हैं तो गैर-गणना योग्य संपत्ति को पुन: सक्रिय नहीं किया जाएगा।
  • पहला बिंदु देखें
  • इनहेरिट की गई संपत्तियों में निर्मित वस्तुओं (धक्का, पॉप, toString ...) की तरह गणनीय

    var o = {a:1, b:2, c:3} // a,b,c are enumerable properties 
    o.propertyIsEnumerable("toString") // returns false, because it is a inherited property 
    for(p in o) console.log(p); // this loop will print a,b and c but not toString or other inherited properies 
    
+2

मेरा मानना ​​है कि तीसरा बिंदु गलत है। विरासत गुण निश्चित रूप से किसी अन्य के रूप में गणित हैं ... 'var x = {a: 1}; var y = Object.create (x); वाई.बी = 2; के लिए (वाई में नाम) {console.log (नाम, वाई [नाम]);} '' 2 2 'और '1' उत्पन्न करता है। –

+0

आप सही हैं! विरासत गुण भी गणित हैं। यदि आप बस अपनी और बहुमूल्य गुणों को ऑब्जेक्ट.की() का उपयोग करना चाहते हैं। – daniatic

11

मुझे लगता है कि एक और बड़ा लाभ यह है कि यह किसी वस्तु के निजी गुणों को सार्वजनिक नामस्थान को प्रदूषित करने से रोकता है।

कहें कि आपने Cosmos नामक एक शक्तिशाली लाइब्रेरी बनाई और प्रकाशित की है। उपयोगकर्ता नोड दुभाषिया ऊपर आग और निर्माता को फोन करके यह का एक नया उदाहरण बनाता है:

var Cosmos = require('Cosmos'); 
var cosmos = new Cosmos('my empire'); 

अब उपयोगकर्ता केवल प्रकार cosmos और प्रेस क्या सार्वजनिक एपीआई इसका समर्थन करता है देखने के लिए दर्ज करें। आप दोनों में से कौन सा उपयोगकर्ता देखना चाहते हैं?

{ name: 'my empire', 
    grow: [Function: grow], 
    addStar: [Function: addStar], 
    beautify: [Function: beautify], 
    implode: [Function: implode], 
    destroy: [Function: destroy] } 

या

{ _age: 25000, 
    _size: 35000, 
    _destroyed: false, 
    name: 'my empire', 
    _numStars: 200, 
    _init: [Function: _init], 
    grow: [Function: grow], 
    _grow: [Function: _grow], 
    addStar: [Function: addStar], 
    _checkStatus: [Function: _checkStatus], 
    beautify: [Function: beautify], 
    implode: [Function: implode], 
    destroy: [Function: destroy] } 
+3

गैर-गणना योग्य गुण अभी भी सार्वजनिक हैं और अभी भी नामस्थान को प्रदूषित करते हैं। यदि आप निजी संपत्ति चाहते हैं, तो आपको बंद करने की आवश्यकता है। – Matthew

+4

मैंने जवाब और महत्वपूर्ण टिप्पणी दोनों को उखाड़ फेंक दिया। टिप्पणी की आलोचना मुझे वैध मानती है, इसलिए शायद उत्तरदाता का "सार्वजनिक" और "निजी" का उपयोग इष्टतम नहीं हो सकता है। हालांकि, मुझे लगता है कि उत्तर का बिंदु अभी भी सहायक है (कम से कम यह मेरे लिए था) क्योंकि यह दिखाता है कि लाइब्रेरी उपयोगकर्ता आसानी से उपयोग करने के लिए लाइब्रेरी लेखक के लाइब्रेरी लेखक के उद्देश्य से कितनी आसानी से देख सकता है (उदाहरण के लिए कृपया ' बढ़ो 'और '_grow' नहीं, भले ही दोनों तकनीकी रूप से सार्वजनिक हों)। –