JavaScript'in "for-in" döngüsünde "var" veya "var" yok mu?


99

for-inJavaScript'te döngü yazmanın doğru yolu nedir ? Tarayıcı, burada gösterdiğim iki yaklaşımdan herhangi biri hakkında şikayette bulunmaz. İlk olarak, yineleme değişkeninin xaçıkça bildirildiği bir yaklaşım vardır :

for (var x in set) {
    ...
}

Ve alternatif olarak daha doğal okuyan ama bana doğru gelmeyen bu yaklaşım:

for (x in set) {
    ...
}

Bohça dosya oluşturulan bir webpack döngü için de hataya neden neden giderirken Sadece bu yazı geldi varyineleyici ilan etmek kullanılmamıştır i: Uncaught ReferenceError: i is not defined. Bundan sonra onu kullanacağım: / webpack "global" değişkenleri tuhaf bir şekilde ele alıyor, daha fazlası için bkz: stackoverflow.com/a/40416826
user1063287

Yanıtlar:


103

Kullanın var, değişkenin kapsamını azaltır, aksi takdirde değişken bir varifadeyi ararken en yakın kapanışı arar . Eğer bir bulamazsa, varo zaman globaldir (katı moddaysanız using strict, global değişkenler bir hata verir). Bu, aşağıdaki gibi sorunlara yol açabilir.

function f (){
    for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2

var iFor döngüsüne yazarsanız uyarı gösterilir 2.

JavaScript Kapsam Belirleme ve Kaldırma


4
Soruyu cevaplamıyor, bu normal döngü için, in için değil.
IllidanS4 Monica'yı

İ == 5'in nedeni, for döngüsündeki var olmamasından daha çok kaldırmaya bağlı değil mi?
Snekse

1
Bunun bir başka önemli yönü de, katı modun gobal özelliklerin örtük olarak oluşturulmasını yasaklamasıdır, bu nedenle standart "for in" döngüsünü var deyimi olmadan kullanmak aslında başarısız olur ve bir ReferenceError döndürür.
dkugappi

2
Ancak, Java'dan geliyor var, forkafanın içini koymak , for döngüsünde yerel gibi görünüyor, ki öyle değil. Bu nedenle aşağıdaki user422039 stilini tercih ediyorum.
njlarsson

2
Ya bir kapsamda birden fazla for-döngüsüne sahipseniz? Ya endeksi yeniden kullanmanız gerekecek (var yok) ya da bir daha asla kullanmayacağınız çok sayıda yeni değişken (j, k, l, m,…) bildirmeniz gerekecek.
armin

40

İlk versiyon:

for (var x in set) {
    ...
}

adlı yerel bir değişken bildirir x. İkinci versiyon:

for (x in set) {
    ...
}

değil.

Eğer x(bir var yani zaten yerel bir değişkendir var x;veya var x = ...;bir yere daha erken geçerli kapsamda (yani şimdiki işlevi)) o zaman eşdeğer olacaktır. Eğer xzaten yerel bir değişken değildir, o zaman ikinci kullanarak örtülü bir küresel değişkeni ilan edecek x. Bu kodu düşünün:

var obj1 = {hey: 10, there: 15};
var obj2 = {heli: 99, copter: 10};
function loop1() {
    for (x in obj1) alert(x);
}
function loop2() {
    for (x in obj2) {
        loop1(); 
        alert(x);
    }
}
loop2();

Uyarının bu beklediğinizden hey, there, heli, hey, there, copter, ancak o zamandan beri xbir ve onu uyaracaktır aynıdır hey, there, there, hey, there, there. Bunu istemezsin! Kullan var xsenin içinde fordöngüler.

Her şeyin üstesinden gelmek için: fordöngü genel kapsamdaysa (yani bir işlevde değilse), yerel kapsam (kullanıyorsanız kapsam xiçinde bildirilir var x) genel kapsam ile aynıdır (kapsam x, içinde dolaylı olarak bildirilir) xvar olmadan kullanırsanız ), bu nedenle iki sürüm aynı olacaktır.


3
Sonunda açıklama ve güzel örnekle tam bir cevap. Ve gerçekten soruyu cevaplıyor.
IllidanS4, Monica'yı

22

Gerçekten yerel değişkenleri bildirmek gerekir var, her zaman .

Ayrıca, yapmak istediğiniz şeyin bu olduğundan kesinlikle emin değilseniz, "for ... in" döngülerini kullanmamalısınız. Gerçek diziler arasında yineleme yapmak için (oldukça yaygındır), her zaman sayısal indeksi olan bir döngü kullanmalısınız:

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}

Düz bir dizi boyunca "for ... in" ile yinelemenin beklenmedik sonuçları olabilir, çünkü döngünüz sayısal olarak dizinlenmiş olanların yanı sıra dizinin özniteliklerini de alabilir.

edit - burada 2015'te .forEach()bir dizi boyunca yineleme yapmak için de kullanılabilir :

array.forEach(function(arrayElement, index, array) {
  // first parameter is an element of the array
  // second parameter is the index of the element in the array
  // third parameter is the array itself
  ...
});

.forEach()Yöntem IE9 ileri gelen Dizi prototip üzerinde bulunur.


12

Aslında, forbaşlık içindeki beyanı sevmiyorsanız , şunları yapabilirsiniz:

var x;
for (x in set) {
    ...
}

Bu soruya verilen diğer yanıtlarda da belirtildiği gibi, hiç kullanmamak var, global bir özellik atamak gibi gereksiz yan etkiler yaratır.


9

Döngü değişkenini ile bildirdiğiniz yeri kullanın var. Örtük olarak bildirilen değişkenlerin farklı bir kapsamı vardır, muhtemelen bu sizin amaçladığınız şey değildir.


9
for(var i = 0; ...)

yaygın olarak görülen bir kalıptır ancak farklıdır

for(int i; ...)

C ++ 'da değişkenin kapsamı forbloğa ayarlanmamasıdır . Aslında, varkapsama alanının (işlev) tepesine kaldırılır, böylece bir yerel i, fordöngüden önce (geçerli kapsamın / işlevin başlangıcından sonra) ve ondan sonra etkin bir şekilde kullanılabilir olacaktır .

Başka bir deyişle, yapmak:

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();

aynıdır:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();

ES6, kapsamı for bloğu ile sınırlamak için let(yerine var) anahtar kelimesine sahiptir .

Tabii ki, örtük globaller yerine yerel değişkenler ( varveya letveya const(ES6'da) ile bildirilenler) kullanmanız GEREKİR.

for(i=0; ...)veya for(i in ...)kullanırsanız "use strict";(gerektiği gibi) ve ibildirilmezse başarısız olur .



4

Bence var performans açısından iyi.

Javascript, x'in başka bir yerde zaten var olup olmadığını görmek için tüm küresel kapsama bakmayacaktır.


3

Genel bir bakış açısına göre, ilk sürüm döngünün kapsamı içinde yaşaması gereken bir dizin içindir, diğeri ise döngünün kurucusunun çağrıldığı kapsamdaki herhangi bir değişken olacaktır.

Döngünün for döngüsü içinde indeksini kullanacaksanız ve bu sonraki satırlarda başkaları tarafından istenmeyecekse, değişkeni "var" ile daha iyi tanımlayın, böylece "x" for döngüsünün indisinin 0 ile başlatıldığından emin olursunuz, Diğeri ise, bu bağlamda başka bir "x" değişkeni varsa, bunun üzerine döngünün indeksi yazılacaktır - bu bazı mantıksal hatalarınız olacaktır -.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.