Подтвердить что ты не робот

Область переменных цикла JavaScript

Просто быстрый вопрос о области видимости переменных JavaScript.

Почему функция alert() печатает значение i вместо возврата undefined?

$(document).ready(function () {
    for(var i = 0; i < 10; i += 1){
    }

     alert("What is 'i'? " + i);
});

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

то есть. What is 'i'? 10'.

4b9b3361

Ответ 1

См. MDN для параметров параметров for -loop:

Выражение (включая выражения присваивания) или объявление переменной. Обычно используется для инициализации переменной счетчика. Это выражение может необязательно объявлять новые переменные с ключевым словом var. Эти переменные не являются локальными для цикла, то есть они находятся в той же области, в которой находится цикл for. Результат этого выражения отбрасывается.

Ответ 2

У JavaScript не было области видимости блока до тех пор, пока let были введены const и let, просто var который является областью действия функции. Поскольку инициализация i находится внутри одной функции, эта переменная доступна в любом месте этой же функции.

От MDN:

Важный: у JavaScript нет блочной области видимости. Переменные, введенные с блоком, попадают в область действия содержащей их функции или сценария, и последствия их установки сохраняются за пределами самого блока. Другими словами, операторы блока не вводят область действия. Хотя "автономные" блоки являются допустимым синтаксисом, вы не хотите использовать автономные блоки в JavaScript, потому что они не делают то, что вы думаете, они делают, если вы думаете, что они делают что-то вроде таких блоков в C или Java.

Ответ 3

Люди javascript пытаются это исправить!

EcmaScript6 (aka EcmaScript 2015) - это последняя версия javascript, прошедшая прошлым летом, и браузеры только начинают поддерживать свои функции.

Одна из этих функций - это локальные переменные локального масштаба с выражением "let". На данный момент (апрель 2016 года) большинство современных версий основных браузеров поддерживают это, кроме Safari. Это поддерживает несколько мобильных браузеров.

Подробнее об этом вы можете прочитать здесь (в частности, см. раздел "Перемещаемые переменные в циклах" ): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Здесь вы можете проверить текущую поддержку браузера (найдите строку Bindings → let): https://kangax.github.io/compat-table/es6/

Ответ 4

В отличие от других языков (например: Java, С++, C), JavaScript не поддерживает область блока. Когда вы объявляете переменную в цикле или в функции, ее область видимости находится внутри тела функции, если вы выполняете

for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

здесь ваша i становится глобальной переменной, а j становится локальной для функции или script, в которой находится цикл.

Ответ 5

for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

неверно утверждать, что приведенное выше создает глобальную переменную i. Я считаю, что вы всегда должны использовать var для объявления переменных (если вы намеренно не хотите "свойство", а не "переменную", что маловероятно в 99,99% сценариев кодирования JS...)

Опускание var при назначении начального значения i не создает локальную или даже глобальную переменную, оно создает свойство i для глобального объекта (что может показаться/вести себя в основном как глобальный переменная - но они имеют некоторые тонкие различия).

лучше было бы:

var i;
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

теперь цикл использует глобальную переменную i (или локальную переменную функции i, если этот код появляется в функции)

подробнее об этом читайте что является функцией ключевого слова var и переменные против свойств в Javascript

- обратите внимание, что немного запутанно, так это то, что вы можете повторно объявить переменную, например, во втором цикле

for(var i=0; i<9; i++){
    document.write('i = ' + i + '<br>');
}


for(var i=0; i<9; i++){
    document.write('i = ' + i + '<br>');
}

это кажется действительным (никаких ошибок при тестировании). Кажется, что вы можете повторно объявить переменные в JavaScript - но, вероятно, это не всякая хорошая идея, если только не специальный случай - см. Этот связанный вопрос, говорящий о том, как [Google Analytics использует "безопасную" переоценку переменной] (Обновление переменной javascript)

существует некоторая дискуссия о повторном объявлении переменных в JS (а также переменных цикла, таких как i) в этом связанном вопросе SO: объявлять переменные внутри или вне цикла

Существует событие шаблон JavaScript для одиночного объявления переменных