--- id: 587d7b87367417b2b2512b40 title: Compare Scopes of the var and let Keywords challengeType: 1 forumTopicId: 301195 localeTitle: Сравнение области действия переменных var и let --- ## Description
Когда вы объявляете переменную с ключевым словом var , она объявляется глобально или локально, если объявляется внутри функции. Ключевое слово let ведет себя аналогично, но с некоторыми дополнительными функциями. Когда вы объявляете переменную с ключевым словом let внутри блока, оператора или выражения, его область действия ограничена этим блоком, оператором или выражением. Например:
var numArray = [];
for (var i = 0; i <3; i ++) {
numArray.push (i);
}
console.log (Numarray);
// возвращает [0, 1, 2]
console.log (i);
// возвращает 3
С ключевым словом var i объявляется глобально. Поэтому, когда i++ выполняется, он обновляет глобальную переменную. Этот код похож на следующий:
var numArray = [];
var i;
for (i = 0; i <3; i ++) {
numArray.push (i);
}
console.log (Numarray);
// возвращает [0, 1, 2]
console.log (i);
// возвращает 3
Такое поведение вызовет проблемы, если вы должны были создать функцию и сохранить ее для последующего использования внутри цикла for, который использует переменную i . Это связано с тем, что хранимая функция всегда будет ссылаться на значение обновленной глобальной переменной i .
var printNumTwo;
for (var i = 0; i <3; i ++) {
if (i === 2) {
printNumTwo = function () {
return i;
};
}
}
console.log (printNumTwo ());
// возвращает 3
Как вы можете видеть, printNumTwo() печатает 3, а не 2. Это связано с тем, что значение, присвоенное i было обновлено, и printNumTwo() возвращает глобальный i а не значение, которое i имел, когда функция была создана в цикле for. Ключевое слово let не следует этому поведению:
"use strict";
let printNumTwo;
for (let i = 0; i <3; i ++) {
if (i === 2) {
printNumTwo = function () {
return i;
};
}
}
console.log (printNumTwo ());
// возвращает 2
console.log (i);
// возвращает «i не определен»
i не определен, потому что он не был объявлен в глобальной области. Он объявляется только в инструкции цикла for. printNumTwo() вернула правильное значение, потому что три разные переменные i с уникальными значениями (0, 1 и 2) были созданы ключевым словом let в цикле.
## Instructions
Исправьте код, чтобы i объявлял в выражении if отдельную переменную, чем i объявленный в первой строке функции. Не забудьте использовать ключевое слово var в любом месте вашего кода. Это упражнение предназначено для иллюстрации разницы между тем, как ключевые слова var и let назначают область видимости для объявленных переменных. При программировании функции, аналогичной той, которая используется в этом упражнении, часто лучше использовать разные имена переменных, чтобы избежать путаницы.
## Tests
```yml tests: - text: var should not exist in code. testString: getUserInput => assert(!getUserInput('index').match(/var/g)); - text: The variable i declared in the if statement should equal "block scope". testString: getUserInput => assert(getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g)); - text: checkScope() should return "function scope" testString: assert(checkScope() === "function scope"); ```
## Challenge Seed
```js function checkScope() { 'use strict'; var i = 'function scope'; if (true) { i = 'block scope'; console.log('Block scope i is: ', i); } console.log('Function scope i is: ', i); return i; } ```
## Solution
```js function checkScope() { 'use strict'; let i = 'function scope'; if (true) { let i = 'block scope'; console.log('Block scope i is: ', i); } console.log('Function scope i is: ', i); return i; } ```