2012-05-24 118 views
11

我JavaScript的閱讀:好的部分...JQuery和Underscore「each」保證數組的順序?

由於JavaScript的數組對象真正的for in語句可用於遍歷所有數組的屬性。不幸的是,在不作任何屬性的順序保證...

據我所知道的「每個」功能的總部設在for in,然後做each函數形式jQuery和下劃線庫爲了保證他們的時候迭代一個數組?我試圖避免令人討厭的標準for

預先感謝您。

+1

確保你清楚數組是什麼以及JavaScript是什麼對象... – Pointy

回答

16

在迭代數組時,始終保證順序。這是當你無法保證時迭代(非數組)對象。順便提一下,陣列仍然是物體。


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

@davidgnin無非就是'for'和'for in'循環。同樣的邏輯適用。 – 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的$.each使用基於length屬性的數字循環。

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並強調似乎優於稀疏陣列,因爲他們忽略了還沒有分配給它們的值索引。