"var "или нет" var "в цикле" for-in " JavaScript?

Как правильно написать for-in цикл в JavaScript? Браузер не выдает жалобу ни на один из двух подходов, которые я показываю здесь. Во-первых, существует такой подход, когда переменная итерации x прямо заявил:

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

и в качестве альтернативы этот подход, который читается более естественно, но не кажется мне правильным:

for (x in set) {
    ...
}

9 ответов


использовать var, это уменьшает область переменной, иначе переменная смотрит до ближайшего закрытия, ища var заявление. Если он не может найти var тогда он глобальный (если вы находитесь в строгом режиме,using strict глобальные переменные выдаст ошибку). Это может привести к следующим проблемам.

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

если вы пишите var i в цикле for предупреждение показывает 2.

JavaScript область и подъем


первый вариант:

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

объявляет локальную переменную x. Вторая версия:

for (x in set) {
    ...
}

нет.

если x уже является локальной переменной (т. е. у вас есть var x; или var x = ...; где-то раньше в вашей текущей области видимости (т. е. текущей функции)), то они будут эквивалентны. Если x еще не является локальной переменной, тогда использование второй неявно объявит глобальную переменную x. Считать это код:

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

вы можете ожидать, что это предупредит hey, there, heli, hey, there, copter, но поскольку x является одним и тем же он будет предупреждать hey, there, there, hey, there, there. Ты этого не хочешь! Использовать var x в своем for петли.

в довершение всего: если for цикл находится в глобальной области (т. е. не в функции), затем локальная область (область x объявляется, если вы используете var x) совпадает с глобальной областью (область x неявно объявляется, если вы используете x без var), поэтому две версии будут идентичными.


вы действительно должны объявить локальные переменные с var, всегда.

вы также не должны использовать "для ... в "циклах", если вы не абсолютно уверены, что это то, что вы хотите сделать. Для перебора настоящих массивов (что довольно часто), вы всегда должны использовать цикл с числовым индексом:

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

итерация через простой массив с помощью " for ... В " может иметь неожиданные последствия, потому что ваш цикл может забрать атрибуты массива, кроме численно индексированные.

редактировать - здесь в 2015 году также можно использовать .forEach() для перебора массива:

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() метод присутствует на прототипе массива от IE9 вперед.


на самом деле, если вам не нравится декларация в for заголовок, вы можете сделать:

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

как упоминалось в других ответах на этот вопрос, не используя var вообще создает ненужные побочные эффекты, такие как назначение глобального свойства.


используйте тот, где вы объявляете переменную цикла с var. Неявно объявленные переменные имеют другую область, которая, вероятно, не соответствует вашим намерениям.


for(var i = 0; ...)

является широко распространенным шаблоном, но он отличается от

for(int i; ...)

в C++ в том, что переменная не ограничивается for блок. На самом деле,var поднимается в верхнюю часть заключительной области (функции), поэтому локальный i будет эффективно доступен как перед for loop (после начала текущей области / функции) и после нее.

другими словами, делать:

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

это же as:

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

ES6 имеет let ключевое слово (вместо var), чтобы ограничить область действия блоком for.

конечно, вы должны использовать локальные переменные (те, которые объявлены с помощью var или let или const (в ES6)), а не неявные глобалы.

for(i=0; ...) или for(i in ...) потерпит неудачу, если вы используете "use strict"; (как следует) и i не заявлен.


используя var является самым чистым способом, но оба работают, как описано здесь:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

в основном, с помощью var убедитесь, что вы создали новую переменную. В противном случае вы можете случайно использовать ранее определенную переменную.


Я думаю, что var хорош по соображениям производительности.

Javascript не будет просматривать всю глобальную область, чтобы увидеть, существует ли x где-то еще.


с общей точки зрения, первая версия будет для индекса, который должен жить в области цикла, в то время как другой будет любой переменной в области, где был вызван конструктор цикла.

Если вы собираетесь использовать индекс цикла внутри цикла, и это не потребуется другим в следующих строках, лучше объявить переменную с "var", чтобы Вы были уверены, что" x " для индекса цикла инициализирован с 0, в то время как другой, если другая переменная "x" доступна в этом контексте, это будет перезаписано индексом цикла - то есть у вас будут некоторые логические ошибки -.