2015-04-16 3 views
0

Я немного озадачен точным порядком выполнения конкретного цикла, с которым я играю, в Кодепене. Проверьте эти две петли, которые и делают то же самое:Каков точный порядок выполнения цикла Javascript?

var a = ['orange','apple']; 
for (var i=0; i<2;i++) { 
    alert(a[i]); 
} 

for (var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

Вы можете увидеть это в действии здесь: http://codepen.io/nickbarry/pen/MYNzLP/

Первый цикл является стандартным, ваниль способ записи для цикла. Как и ожидалось, он предупреждает «оранжевый», затем «яблоко».

Я написал второй цикл, используя предложение от MDN (поиск «идиомы», здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript).

Это работает, но я не совсем понимаю, почему. Мое понимание для циклов, которое явно некорректно (более чем одним способом?), Таково: * Цикл for оценивает правдоподобие второго выражения перед его запуском в первый раз. Таким образом, кажется, что, когда цикл for оценивает правдивость второго выражения, он должен увеличивать j до установки значения фруктов. Поэтому в первый раз через петлю фрукты должны быть равны «яблоко». * И цикл должен запускаться только один раз, потому что после первого раза, когда он снова оценивает второе выражение, чтобы увидеть, если он все еще верен, он должен еще раз увеличить j до того, как он вернет значение для фруктов, а поскольку нет значение в позиции индекса 2, оно должно возвращать результат ложности и выйти из цикла.

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

Кроме того, автор статьи MDN, похоже, понравился второй способ написания цикла - есть ли причина, по которой это лучше? Он использует меньшее количество символов, что хорошо, я думаю. Пропускает ли третье выражение в цикле for сохранение значительного времени? Или это просто «круто, потому что это умно»?

+1

Причина, по которой он работает, заключается в том, что это пост-приращение, а не предварительное приращение. Ваши предположения были бы истинными, если бы это был '++ j' вместо' j ++ '. –

+1

Второй способ написания цикла отлично, если ваша цель - сделать врагов. Нет никакой реальной выгоды, ее труднее читать, она будет преждевременно останавливаться, если в массиве есть значение ложности, и это, вероятно, медленнее (хотя тестирование необходимо обязательно). –

+1

Обратите внимание, что MDN - это wiki. Любой полудух может добавлять контент. В этой же статье на самом деле предлагается 'for-in' для массивов, не давая полного объяснения всех проблем, которые могут возникнуть. –

ответ

5
for (var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

В псевдокоде равно:

initialize j = 0 and fruit = undefined 

assign fruit = a[j] (j = 0, fruit = 'orange') 
j = j + 1 (j = 1) 
check fruit for being truthy (true) 

alert(fruit) ('orange') 

assign fruit = a[j] (j = 1, fruit = 'apple') 
j = j + 1 (j = 2) 
check fruit for being truthy (true) 

alert(fruit) ('apple') 

assign fruit = a[j] (j = 2, fruit = undefined) 
j = j + 1 (j = 3) 
check fruit for being truthy (false) 

exit loop 

Важное примечание:

Постфиксная унарный ++ оператор работает как:

  1. Отдаем текущее значение из переменная
  2. Мы увеличиваем значение переменной

ли пропуск третьего выражения в цикле существенно сэкономить время?

Это не спасает ничего вообще

Кроме того, автор статьи MDN, казалось, как второй способ написания цикла - есть причина того, что путь лучше?

Это не лучше.Автор просто думает, что это круто, а автору нравится быть крутым (пока это не так).

+0

Спасибо, это именно тот ответ, который мне нужен! –

0

А для цикла это всего лишь сокращенный способ написания цикла while. , например. этот цикл

for(var i = 0, j = 10; i < 10; i++, j++) { 
    alert(i + ", " + j); 
} 

просто короткий путь написания

var i = 0, j = 10; 
while(i < 10) { 
    alert(i + ", " + j); 
    i++; j++; 
} 

, так что Ман этого цикла

for(var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

таким же, как это

var j = 0, fruit; 
while(fruit = a[j++]) { 
    alert(fruit); 
} 
0

Вы можете следить через порядок выполнения JavaS for петля cript, используя SlowmoJS: http://toolness.github.io/slowmo-js/

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

Смежные вопросы