JavaScript'te bir dizi üzerinde for-each?
JavaScript kullanarak bir dizideki tüm girdiler arasında nasıl döngü yapabilirim?
Bunun gibi bir şey olduğunu düşünmüştüm:
forEach(instance in theArray)
Burada theArray
benim dizimdir, ancak bu yanlış gibi görünüyor.
4427
3
TL;DR
for-of
döngüsü (yalnızca ES2015+),Array#forEach
([spec
][1] | [MDN
][2]) (veyasome
ve benzeri akrabaları) (sadece ES5+),for
döngüsü,ya da koruma önlemleriyle birlikte "içeride". Ancak keşfedilecek daha çok şey var, okumaya devam edin...
JavaScript, diziler ve dizi benzeri nesneler arasında döngü oluşturmak için güçlü anlambilimlere sahiptir. Cevabı iki bölüme ayırdım: Gerçek diziler için seçenekler ve
arguments
nesnesi, diğer yinelenebilir nesneler (ES2015+), DOM koleksiyonları vb. gibi sadece dizi benzeri şeyler için seçenekler. ES2015 seçeneklerini şimdi ES5 motorlarında bile ES2015'ten ES5'e transpiling yaparak kullanabileceğinizi hemen belirteyim. Daha fazlası için "ES2015 transpiling" / "ES6 transpiling" araması yapın... Tamam, seçeneklerimize bakalım:Gerçek Diziler İçin
Şu anda en geniş şekilde desteklenen sürüm olan [ECMAScript 5][3] ("ES5")'te üç seçeneğiniz vardır ve [ECMAScript 2015][4] ("ES2015", "ES6")'te iki tane daha eklenmiştir:
for
döngüsü kullanın1. forEach` ve ilgili kullanın
ES5 tarafından eklenen
Array
özelliklerine erişiminizin olduğu (doğrudan veya polyfills kullanarak) herhangi bir belirsiz modern ortamda (yani IE8 değil),forEach
([spec
][1] | [MDN
][2]) kullanabilirsiniz:forEach
bir geri çağırma fonksiyonu ve isteğe bağlı olarak bu geri çağırmayı çağırırken
thisolarak kullanılacak bir değer kabul eder (yukarıda kullanılmamıştır). Geriçağırım, seyrek dizilerde var olmayan girdileri atlayarak, dizideki her girdi için sırayla çağrılır. Yukarıda sadece bir argüman kullanmış olmama rağmen, geri çağrı üç argümanla çağrılır: Her bir girdinin değeri, o girdinin indeksi ve üzerinde yineleme yaptığınız diziye bir referans (fonksiyonunuzda zaten yoksa). IE8 gibi eski tarayıcıları desteklemediğiniz sürece (NetApps bu yazının yazıldığı Eylül 2016 itibariyle pazar payının %4'ün biraz üzerinde olduğunu gösteriyor),
forEach'i genel amaçlı bir web sayfasında şim olmadan rahatlıkla kullanabilirsiniz. Eski tarayıcıları desteklemeniz gerekiyorsa,forEach
için shimming/polyfilling kolayca yapılabilir (çeşitli seçenekler için "es5 shim" araması yapın). forEach, yineleme işlevine argüman olarak sağlandıkları ve sadece o yineleme için güzel bir şekilde kapsamlandırıldıkları için, dizinleme ve değer değişkenlerini içeren kapsamda bildirmek zorunda kalmamanız gibi bir avantaja sahiptir. Her dizi girişi için bir fonksiyon çağrısı yapmanın çalışma zamanı maliyeti konusunda endişeleniyorsanız, endişelenmeyin; [details](http://blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html). Ek olarak,
forEach' "hepsinde döngü" işlevidir, ancak ES5, aşağıdakiler de dahil olmak üzere diğer birçok yararlı "dizi boyunca yolunuzu çalışın ve bir şeyler yapın" işlevini tanımlamıştır:every
][5] (geri çağırmafalse
ya da başka bir şey döndürdüğünde döngüyü durdurur)some
][6] (geri arama ilk keztrue
veya doğru bir şey döndürdüğünde döngüyü durdurur)filter
][7] (filtre işlevinintrue
döndürdüğü öğeleri içeren vefalse
döndürdüklerini çıkaran yeni bir dizi oluşturur)map
][8] (geri arama tarafından döndürülen değerlerden yeni bir dizi oluşturur)reduce
][9] (önceki değerleri aktararak geri çağrıyı tekrar tekrar çağırarak bir değer oluşturur; ayrıntılar için spesifikasyona bakın; bir dizinin içeriğini ve diğer birçok şeyi toplamak için kullanışlıdır)reduceRight
][10] (reduce
gibi, ancak artan yerine azalan sırada çalışır)2. Basit bir
for
döngüsü kullanınBazen eski yöntemler en iyisidir:
Dizinin uzunluğu döngü sırasında değişmeyecekse ve performansa duyarlı bir koddaysa (pek olası değil), uzunluğu önceden yakalayan biraz daha karmaşık bir sürüm tiny biraz daha hızlı olabilir:
Ve / veya geriye doğru sayma:
Ancak modern JavaScript motorlarıyla, son bir parça güç elde etmeniz nadiren gerekir. ES2015 ve daha yüksek sürümlerde, indeks ve değer değişkenlerinizi
for
döngüsü için yerel yapabilirsiniz:Bunu yaptığınızda, her döngü yinelemesi için yalnızca
value
değil,index
de yeniden oluşturulur, yani döngü gövdesinde oluşturulan kapanışlar, o belirli yineleme için oluşturulanindex
e (vevalue
ya) bir referans tutar:Eğer beş div'iniz olsaydı, "Index is: 0" ve eğer ilkine tıklarsanız "Index is: 4" eğer sonuncuya tıklarsanız. Eğer
let' yerine
var' kullanırsanız bu çalışmaz.3. for-in` doğru şekilde kullanın
İnsanlar size
for-in' kullanmanızı söyleyecektir, ancak
for-in' bunun için değildir][11]. for-inbir nesnenin *sayılabilir özellikleri* üzerinde döngü yapar, bir dizinin indeksleri üzerinde değil. ES2015'te (ES6) bile **sıra garanti edilmez**. ES2015+ nesne özellikleri için bir sıra tanımlar ([
[[OwnPropertyKeys]]](https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys), [
[[Enumerate]]](https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-enumerate) ve [
Object.getOwnPropertyKeys][12] gibi bunları kullanan şeyler aracılığıyla), ancak
for-inin bu sırayı izleyeceğini **tanımlamaz**. (Ayrıntılar [bu diğer yanıtta][13].) Bir dizi üzerinde
for-in` için tek gerçek kullanım durumları şunlardır:for-in
kullanabilirsiniz:Not: Bu cevap umutsuzca güncelliğini yitirmiştir. Daha modern bir yaklaşım için bir dizi üzerinde kullanılabilen yöntemler'e bakın. İlgi çekici yöntemler şunlar olabilir:
JavaScript]2'de bir diziyi yinelemenin standart yolu vanilla
for
döngüsüdür:Bununla birlikte, bu yaklaşımın yalnızca yoğun bir diziniz varsa ve her dizin bir eleman tarafından işgal ediliyorsa iyi olduğunu unutmayın. Dizi seyrekse, dizide gerçekte var olmayan birçok indis üzerinde yineleme yapacağınızdan, bu yaklaşımla performans sorunlarıyla karşılaşabilirsiniz. Bu durumda, bir
for .. in
döngüsü daha iyi bir fikir olabilir. Bununla birlikte,for..in
döngüsü eski tarayıcılarda da numaralandırılacağından veya ek özelliklerenumerable
olarak tanımlanmışsa, dizinin yalnızca istenen özelliklerinin (yani dizi öğelerinin) üzerinde işlem yapılmasını sağlamak için uygun önlemleri almalısınız.ECMAScript 5]3'te dizi prototipi üzerinde bir forEach yöntemi olacaktır, ancak eski tarayıcılarda desteklenmemektedir. Dolayısıyla, bunu tutarlı bir şekilde kullanabilmek için ya bunu destekleyen bir ortama sahip olmanız (örneğin, sunucu tarafı JavaScript için Node.js) ya da bir "Polyfill" kullanmanız gerekir. Bununla birlikte, bu işlevsellik için Polyfill önemsizdir ve kodun okunmasını kolaylaştırdığından, dahil edilmesi iyi bir polyfill'dir.
Bir dizi üzerinde döngü yapmak istiyorsanız, standart üç parçalı
for
döngüsünü kullanın.myArray.length` dosyasını önbelleğe alarak veya geriye doğru yineleyerek bazı performans optimizasyonları elde edebilirsiniz.