2012-05-24 14 views
11
JavaScript okumaya

: JavaScript'in diziler gerçekten nesneleri olduğundan İyi Parçaları ...JQuery ve Underscore "her" bir dizi için garanti siparişi?

, for in ifadesi bir dizinin tüm özelliklerini üzerinde yineleme için kullanılabilir. Ben "her" işlevleri for in dayanır bildiği gibi maalesef in için Bildiğim kadarıyla özelliklerinin sipariş hakkında hiçbir garanti ...

yapar, sonra each fonksiyon formu JQuery yapar ve Underscore kütüphaneleri siparişi ne zaman garanti bir dizi üzerinde yinelemek? Sinir bozucu standart olan for'dan kaçınmaya çalışıyorum.

Önceden teşekkür ederiz.

+1

Bir Array öğesinin ne olduğunu ve bir Nesnenin JavaScript'te neler olduğunu netleştirdiğinizden emin olun ... – Pointy

cevap

16

Bir diziden yinelediğinizde, sipariş her zaman garanti edilir. Bu, (dizi olmayan) nesneler boyunca yinelediğinizde, hiçbir garanti olmadığında ortaya çıkar. Diziler hala yoldalar.


each dizisi benzeri bir nesne için for in ve for daha fazla değildir. çerçeve, iş için doğru döngüyü belirler ve aynı mantık geçerlidir: Nesne yineleme yapılmıyorken, dizi yinelemeleri düzenlidir.

alt çizgi kaynak:

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'nin kaynak:

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

Sorunun açık olduğunu düşündüğümden eminim. Nesneler/diziler konusundaki işlevlerden daha çok endişeleniyorum. – davidgnin

+0

@davidgnin her biri 'for' ve' in 'döngülerinden başka bir şey değildir. Aynı mantık geçerlidir. – Joseph

+0

Teşekkür ederiz! Sonra dizilerde her biri için değil, içeride değil. Tam olarak bilmeye çalıştığım buydu. – davidgnin

3

iki yolu yapabilirsiniz dizisi üzerinde döngü vardır: bir dizinin endeksli elemanları üzerinde sayısal bir döngü ya da bir for in, bir dizinin nesne özellikleri üzerinden nesnesi üzerinde döngü.

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

o özellikler belirlendi sırasıdır, bu durum 0 1 3 2 foo döndürür (ancak tarayıcınız bile, ya o davranışı sergilemek gerekiyor hiçbir söz yoktur).

Şimdiye kadar, sayısal döngüler daha iyi görünüyor, ancak yedek dizileri, yani boşlukları olan dizileri kaldıramazlar. ES5 Array.forEach belirtilmemiş değerleri atlar, jQuery $.each ise length özelliğine dayalı bir sayısal döngü kullanır.

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); }) 

Yani, hem forEach ve $.each endeks sırayla değerleri döndürür, ancak kendilerine atanmış bir değere olmadı dizinleri görmezden beri forEach ve Underscore, seyrek diziler için üstün görünüyor.

İlgili konular