2010-02-15 4 views
62

एक सरल शून्य आधारित, संख्यानुसार अनुक्रमित सरणी को देखते हुए:जावास्क्रिप्ट में खराब अभ्यास माना जाता है के साथ '(सूची में var आइटम)' क्यों है?

var list = ['Foo', 'Bar', 'Baz']; 

कई बार, मैं देखा है जब कोई इस तरह एक सरणी में चर के माध्यम से पाशन पता चलता है कि:

for(var item in list) { ... } 

... वहाँ है लगभग निश्चित रूप से कोई सुझाव देता है कि यह बुरा अभ्यास है और वैकल्पिक दृष्टिकोण सुझाता है:

var count = list.length; 

for(var i = 0; i < count; i++) { 
    var item = list[i]; 
    ... 
} 

क्या तर्क है ऊपर के सरल संस्करण का उपयोग नहीं कर रहे हैं और इसके बजाय दूसरे उदाहरण का उपयोग करने के लिए?

+0

36 गुना तेजी से साबित हुई तुम्हें पता है, कि पाश के साथ से अधिक आइटम पाशन नहीं कर रहे हैं आप कुंजी/संपत्ति के नाम/indizes से अधिक पाशन कर रहे हैं। – Bergi

+2

विक्टोरियन टोफैट्स में सी कोडर भी iiterators को समझ नहीं है। हालांकि इसकी स्पिटिंग कुंजी को ध्यान में रखें, मूल्यों पर नहीं। के लिए (;;) प्रारूप तेज है, लेकिन 99% समय, यह वास्तव में कोई फर्क नहीं पड़ता। कोडर समय गणना गणना समय से अधिक महंगा है जब तक कि आप मेगाप्रोजेक्ट्स या ऑप्टिमाइज़ेशन की वास्तविक आवश्यकता वाले सामान पर काम नहीं करते। – Shayne

उत्तर

76

सबसे पहले, लूप का क्रम for...in लूप के लिए अपरिभाषित है, इसलिए कोई गारंटी नहीं है कि आपके इच्छित क्रम में गुणों को फिर से चालू किया जाएगा।

दूसरा, for...in किसी ऑब्जेक्ट के सभी समृद्ध गुणों पर पुनरावृत्त करता है, जिसमें इसके प्रोटोटाइप से विरासत शामिल है। सरणियों के मामले में, यह आप को प्रभावित कर सकता है, तो अपने कोड या किसी पुस्तकालय अपने पेज में शामिल Array के प्रोटोटाइप है, जो एक सही मायने में उपयोगी बात करने के लिए हो सकता है संवर्धित किया:

Array.prototype.remove = function(val) { 
    // Irrelevant implementation details 
}; 

var a = ["a", "b", "c"]; 

for (var i in a) { 
    console.log(i); 
} 

// Logs 0, 1, 2, "remove" (though not necessarily in that order) 
+2

तब तक ठीक है जब तक आप 'hasOwnProperty' का उपयोग करते हैं - 'के लिए (var i a a) {if (a.hasOwnProperty (i)) console.log (i); } '-> 1 2 3 –

+9

एक सुझाव, 'सभी गुणों पर' '** से अधिक ** मूल्यवान ** गुणों को बदलें। नए जावास्क्रिप्ट कार्यान्वयन में, गुणों को 'गलत' पर सेट 'गणना करने योग्य' विशेषता के साथ परिभाषित किया जा सकता है। अंतर्निहित जावास्क्रिप्ट ऑब्जेक्ट्स के ये गुण और गुण 'के लिए ... इन' में दिखाई नहीं देंगे। –

+4

@ डिमिटर: दरअसल, यद्यपि आपने इसे जोड़ने के बाद, लूप को लूप के लिए मानक सी-शैली की तुलना में सरल दिखना बंद कर दिया है। –

0

list.foo = bar; जोड़ें और इस्तेमाल करने की कोशिश सरल for। यदि आप कुछ पुस्तकालयों (जैसे प्रोटोटाइपजेएस) का उपयोग नहीं करते हैं और सरणी ऑब्जेक्ट में कोई भी नई गुण नहीं जोड़ते हैं - तो आप सरल कथन का उपयोग कर सकते हैं।

1

यदि आप उस तरह के लिए उपयोग करते हैं, item स्ट्रिंग मानों "0", "1", ... के माध्यम से गणना करता है, तो सूची में वास्तविक वस्तुएं नहीं। तो पहले स्निपेट में 'आइटम' दूसरे स्निपेट में i की तरह है, item नहीं। इसके अलावा स्ट्रिंग मानों की गणना की जाती है जहां आप संख्याओं की अपेक्षा करेंगे। और जब आप सूची में गुणों की तरह array.ID = "a123" की तरह परेशानी में पड़ते हैं, क्योंकि वे भी गणना करेंगे।

लेकिन इन डाउनसाइड्स के साथ, मुझे अभी भी लगता है कि वाक्यविन्यास बहुत उपयोगी है, अगर आपकी टीम को यह पता है कि यह क्या करता है।

16

गति?

for(..;..;..) पाश से for .. inwhen I tested it here.

Link courtesy this SO answer

+4

मुझे गलत लगता है कि अनंत पाश सामान्य लूप की तुलना में 36x तेज है। लिंक +1 के लिए धन्यवाद। –

+0

@ थॉमस उचित गलतफहमी - संदर्भ के बाहर पढ़ने पर। फिक्स्ड :) – Amarghosh