2013-08-31 3 views
5
for(var i = 0; i < 100; i++){ 
    var foo = 5; 

} 

Это работает ... но разве это плохо?Объявление переменных несколько раз

Я знаю, что могу объявить var foo снаружи, но зачем это делать, когда я буду использовать его только в цикле?

+11

Фактически, он объявляется только один раз. Все объявления переменных поднимаются в верхней части их области (начало функции или глобальная область). Блоки не создают область видимости в JavaScript. – bfavaretto

+0

@bfavaretto: По крайней мере, пока нет. – elclanrs

+0

Несмотря на то, что семантика действует как описанная bfavaretto, я предпочитаю «держать объявления закрытыми» на сайте использования. Это не изменит поведение кода, но я нахожу *, что он делает цель кода более понятной, и я могу сканировать код, чтобы увидеть, что-то выглядит подозрительно неуместным. Другие могут не согласиться, и это нормально. – user2246674

ответ

3

С течением времени мой личный стиль стал более предпочтительным для объявления переменных, где они «на самом деле» находятся в «разуме» конкретного языка, в котором я работаю. Для JavaScript это означает размещение объявлений переменных и функций в позициях, где язык все равно их поднимет.

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

В этом конкретном случае я не ставил бы var foo = 5; декларацию в тело цикла for по той простой причине, что он не делает то, что, по-видимому, делает, т. Е. На самом деле он не обновляется/повторное определение переменной с каждой итерацией. (Размещение объявления var в части инициализации заголовка цикла цикла (инициализация, условие; последумность) было бы более разумным и, конечно же, правильным местом для размещения на языках, которые имеют переменные уровня блока, например, когда JavaScript завершает принятие let -style декларации для охвата уровня блока)

Примечания:.

  • Эта практика может не показаться "нормальными". Мой ум предпочитает держать переменные «близкими» к их использованию, и моя текущая практика не приходит естественным образом к тому, как мой ум работает. Но как программист на протяжении многих лет, опыт с путаницей, плохой коммуникацией, непониманием, недостижимым кодом, который невозможно разгадать и т. Д., Более чем оправдал дополнительную дисциплину, которая требует от меня следовать этому стилю объявления переменных в местах, соответствующих их независимо от языка.

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

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

P.S. Можно было бы указать, что некоторые функции настолько велики, что эта практика делает объявления переменных в конечном итоге страниц далеко от того, где они используются. Да, я видел код, где это правда, и, возможно, даже код, где это невозможно. Тем не менее я не могу не заметить параллели, что одинаково верно для авторов прозы, как для программистов. По мере увеличения уровня навыков длина предложений авторов (и размеров функций программистов) имеет тенденцию к росту, а затем по мере того, как уровень навыков продолжает расти еще выше, длины предложений (и размеры функций программиста) имеют тенденцию сокращаться один раз Больше.

+0

Убедитесь, что ваши методы невелики, тогда вам не нужно столько переменных во многих местах. Но я также предпочитаю объявлять переменные, где они используются, даже если они поднимаются. –

3

Это плохо, потому что это дает ложное впечатление, что i и foo являются локальными переменными.

for(var i = 0; i < 100; i++){ 
    var foo = 5; 
} 
foo; // 5 

Это не может быть проблемой с простым кодом, но если вы используете замыкание становится очевидным, что существует только один foo:

var counters = []; 
for (var i = 0; i < 100; i++) { 
    var foo = 5; 
    counters.push(function() { foo++; return foo; }); 
} 
counters[0](); // 6 
counters[0](); // 7 
counters[1](); // 8 (!) 

Чтобы создать foo в другой области функции должна быть введены:

var counters = []; 
for (var i = 0; i < 100; i++) { 
    (function() { 
     var foo = 5; 
     counters.push(function() { foo++; return foo; }); 
    })(); 
} 
counters[0](); // 6 
counters[0](); // 7 
counters[1](); // 6 

Вот реальный пример вещей происходит неправильно из-за этого: setTimeout in for-loop does not print consecutive values

С JavaScript 1.7 вы можете использовать ключевое слово let (см. MDN) для создания истинных локальных переменных.

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