2012-05-24 19 views
11

मैं जावास्क्रिप्ट पर पढ़ें: अच्छी पार्ट्स ...JQuery और अंडरस्कोर "प्रत्येक" एक सरणी के लिए गारंटी आदेश?

के बाद से JavaScript की सरणियों वास्तव में वस्तुओं रहे हैं, for in बयान एक सरणी के गुणों का सब कुछ खत्म हो पुनरावृत्ति करने के लिए इस्तेमाल किया जा सकता। दुर्भाग्य से, में के लिए गुणों के आदेश के बारे में कोई गारंटी नहीं है ...

बनाता है जहां तक ​​मेरा "प्रत्येक" कार्यों for in में आधारित हैं पता है, तो each फंक्शन फॉर्म JQuery करता है और अंडरस्कोर पुस्तकालयों आदेश जब वे की गारंटी एक ऐरे पर फिर से? मैं कष्टप्रद मानक for से बचने की कोशिश कर रहा हूं।

अग्रिम धन्यवाद।

+1

सुनिश्चित करें कि आप स्पष्ट हैं कि ऐरे क्या है और जावास्क्रिप्ट में कोई ऑब्जेक्ट क्या है ... – Pointy

उत्तर

16

जब किसी सरणी के माध्यम से पुनरावृत्त होता है, तो आदेश हमेशा गारंटीकृत होता है। यह तब होता है जब आप (गैर-सरणी) ऑब्जेक्ट्स के माध्यम से पुनरावृत्ति करते हैं जब कोई गारंटी नहीं होती है। Arrays अभी भी रास्ते से वस्तुओं रहे हैं।


each वस्तुओं के लिए एक for in, और for सरणी की तरह के लिए अधिक नहीं है। ढांचा नौकरी के लिए सही पाश निर्धारित करता है और एक ही तर्क लागू होता है: ऑब्जेक्ट पुनरावृत्ति क्रमशः ऑब्जेक्ट पुनरावृत्ति नहीं है।

अंडरस्कोर के स्रोत:

var each = _.each = _.forEach = function (obj, iterator, context) { 
     if (obj == null) return; 
     if (nativeForEach && obj.forEach === nativeForEach) { 
      obj.forEach(iterator, context); 
     } else if (obj.length === +obj.length) { 
      for (var i = 0, l = obj.length; i < l; i++) { 
       if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; 
      } 
     } else { 
      for (var key in obj) { 
       if (_.has(obj, key)) { 
        if (iterator.call(context, obj[key], key, obj) === breaker) return; 
       } 
      } 
     } 
    }; 

jQuery के स्रोत:

each: function (object, callback, args) { 
    var name, i = 0, 
     length = object.length, 
     isObj = length === undefined || jQuery.isFunction(object); 
    if (args) { 
     if (isObj) { 
      for (name in object) { 
       if (callback.apply(object[name], args) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.apply(object[i++], args) === false) { 
        break; 
       } 
      } 
     } 
     // A special, fast, case for the most common use of each 
    } else { 
     if (isObj) { 
      for (name in object) { 
       if (callback.call(object[name], name, object[name]) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.call(object[i], i, object[i++]) === false) { 
        break; 
       } 
      } 
     } 
    } 
    return object; 
} 
+0

मैंने सवाल संपादित किया क्योंकि मुझे लगता है कि यह स्पष्ट नहीं था। मैं वस्तुओं/सरणी मुद्दे से अधिक कार्यों के बारे में चिंतित हूं। – davidgnin

+0

@ डेविडिगन प्रत्येक 'के लिए' और 'इन' लूप के अलावा कुछ भी नहीं है। वही तर्क लागू होता है। – Joseph

+0

धन्यवाद! फिर प्रत्येक के लिए सरणी में, अंदर नहीं है। यह बिल्कुल ठीक था कि मैं जानना चाहता था। – davidgnin

3

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

var a = ['a','b']; 
a[3] = 'e'; 
a[2] = 'd'; 
a.foo = function() { }; 
for(key in a) 
    console.log(key); 

यह 0 1 3 2 foo देता है, के बाद से है कि आदेश गुण परिभाषित किया गया है (लेकिन कोई वादा है कि आपके ब्राउज़र भी, कि व्यवहार प्रदर्शन करने की जरूरत है या तो है)।

अब तक, संख्यात्मक लूप बेहतर दिखते हैं, लेकिन वे अतिरिक्त सरणी, यानी, अंतराल के साथ सरणी संभाल नहीं सकते हैं। ES5 Array.forEach अनिर्दिष्ट मानों को छोड़ देता है, जबकि jQuery का $.eachlength संपत्ति के आधार पर एक संख्यात्मक पाश का उपयोग करता है।

var a = [1,2]; 
a[1000000] = 4; 
a[9000] = 3; 
a.foo = function() {}; 

// outputs 0, 1, 9000, 1000000 -- note they are in order 
a.forEach(function(elem, index){ console.log(index); }) 

// outputs 0, 1, 9000, 1000000 -- same as above 
_.each(a, function(elem, index){ console.log(index); }) 

// outputs a million values and locks up your browser for a while 
$.each(a, function(index){ console.log(index); }) 

तो, दोनों forEach और $.each सूचकांक क्रम में अपने मान, लेकिन forEach और अंडरस्कोर विरल सरणियों के लिए बेहतर लग रहे हैं, क्योंकि वे अनुक्रमणिका कि उन्हें सौंपे गए एक मूल्य नहीं किया है पर ध्यान न दें।