#javascript #loops #for-loop #nested-loops
#javascript #циклы #for-цикл #вложенные циклы
Вопрос:
Некоторые статические языки, такие как Java, похоже, имеют особые правила для переменных, определенных в первом аргументе цикла for . Они доступны только для данного цикла, что заставляет их вести себя почти так же, как локальные переменные и аргументы функций javascript. Я имею в виду такие вещи, как это:
class ForVariable {
public static void main(String[] args) {
for(int i = 0; i != 0; i ) {}
System.out.println(i); // Throws an Exception
}
}
Javascript ведет себя иначе, что делает вложенные циклы довольно запутанным делом. Мой вопрос: допустимо ли объявлять переменные в последующих циклах с помощью ключевого слова var? Другими словами — какой из следующих примеров допустим?
for(var i = 0, j; i < 5; i ) {
for(j = 0; j < 10; j ) <do some stuff>;
}
или
for(var i = 0; i < 5; i ) {
for(var j = 0; j < 10; j ) <do some stuff>;
}
Очевидно, что неправильно объявлять переменную несколько раз, что сделало бы 2-й пример невозможным, но, учитывая тот факт, что 1-й пример — это способ вложения циклов в большинстве языков, которые я знаю, я довольно нерешительно объявляю победителя.
Комментарии:
1. В javascript нет понятия области действия блока, только область действия функции, использование
var
ключевого слова в объявлениях цикла (или внутриif
s) имеет тот же эффект, что и объявление сvar
ключевым словом в начале функции. (в отличие от Java, C и других)2. Правильно. Но это означало бы, что те
var
, которые находятся во вложенных циклах, будут выполняться несколько раз, что не кажется слишком допустимым решением, или?3. Нет реальной проблемы с использованием
var
много раз (но иногда может быть логическая ошибка). В случае (блокировки цикла) переменные будут доступны только за пределами блоков цикла, и вы можете столкнуться со странными проблемами, если вы ожидаете область действия блока в случае, если вы используете одно и то же имя для переменных.
Ответ №1:
Оба они действительны. Область действия функции и область действия блока. По сути, оба цикла в JavaScript становятся:
function a () {
var i, j;
for(i = 0, j; i < 5; i ) {
for(j = 0; j < 10; j ) <do some stuff>;
}
}
потому var
что объявления поднимаются на вершину
Комментарии:
1. Ну,
a = 1;
выполнение в глобальной области будет иметь тот же эффект,var a = 1; var a = 1; var a = 1;
что и . Это, однако, не делает ни один из них допустимым определением переменной, о чем и был мой вопрос.2. Я сказал вам, что они оба являются действительными друзьями, но я попытался объяснить, почему они оба действительны из-за подъема и области видимости в JavaScript
3. Хорошо, спасибо за предоставленные подробности, я понимаю вашу точку зрения. 🙂
Ответ №2:
Нет ничего плохого в том, чтобы объявлять переменную несколько раз. Например, на самом деле нет проблем с:
var i = 0;
var i = 1;
Это допустимый JavaScript. Хорошие инструменты, такие как компилятор закрытия, будут генерировать предупреждение, хотя, потому что вы обычно не собираетесь этого делать.
При этом даже компилятор закрытия не выдаст предупреждение для вашего примера # 2. Это просто обычное соглашение в JS, даже если вы технически повторно объявляете.
Любой из ваших двух примеров хорош, но второй немного более разумный для анализа. Я бы не стал беспокоиться об этом в любом случае.
Комментарии:
1. Спасибо за ответ. Не является ли, однако, плохой практикой объявлять одну и ту же переменную несколько раз в одной и той же области?
var
s иfunction
s — первоклассные граждане в javascript, что может немного замедлить подготовку области видимости, не так ли?2. ну, компилятор фактически объявит его только один раз в начале функции, поэтому во время выполнения он не будет медленнее. Посмотрите «Подъем JavaScript», чтобы понять, почему это так.
Ответ №3:
Вы не хотите использовать var
ключевое слово, а скорее аргументы функции, потому что javascript не ограничен блоками. Например:
[100,200,300].forEach(function (x,i) {
[10,20,30].forEach(function (y,j) {
console.log('loop variables, indices ' [i,j] ' have values: ' [x,y]);
});
})
или
[100,200,300].map(function (x,i) {
return [10,20,30].map(function (y,j) {
return x y;
});
})
// result: [[110,120,130],[210,220,230],[310,320,330]]
Комментарии:
1. Верно, как я уже сказал, это грязный бизнес, который делает методы ECMA5 блаженством. Однако это на самом деле не отвечает на мой вопрос. 🙂
2. @Witiko: Ах, упс, разработчик, который действительно знает вещи. =) Извините, я думал, вы просто спрашиваете: «Как заставить работать вложенный цикл for?» не углубленный синтаксический вопрос. Надеюсь, кто-то еще может пролить свет, или вы можете посмотреть ecma-international.org/publications/standards/Ecma-262.htm Желаю удачи. (С тем же успехом можно оставить ответ здесь для справки для других.)