135 lines
5.4 KiB
Markdown
135 lines
5.4 KiB
Markdown
![]() |
---
|
|||
|
id: 587d7b87367417b2b2512b40
|
|||
|
title: Порівняйте можливості ключових слів var та let
|
|||
|
challengeType: 1
|
|||
|
forumTopicId: 301195
|
|||
|
dashedName: compare-scopes-of-the-var-and-let-keywords
|
|||
|
---
|
|||
|
|
|||
|
# --description--
|
|||
|
|
|||
|
Якщо ви ще не знаєте про `let`, то перегляньте [це завдання](/learn/javascript-algorithms-and-data-structures/basic-javascript/explore-differences-between-the-var-and-let-keywords).
|
|||
|
|
|||
|
Коли ви задаєте змінну з ключовим словом `var`, вона стане глобальною або локальною, якщо буде оголошена у рамках функції.
|
|||
|
|
|||
|
Ключове слово `let` функціонує схожим чином, але з додатковими можливостями. Коли ви задаєте змінну з ключовим словом `let` у блоці, команді чи виразі, її можливості обмежуються цим блоком, виразом чи виразом.
|
|||
|
|
|||
|
Наприклад:
|
|||
|
|
|||
|
```js
|
|||
|
var numArray = [];
|
|||
|
for (var i = 0; i < 3; i++) {
|
|||
|
numArray.push(i);
|
|||
|
}
|
|||
|
console.log(numArray);
|
|||
|
console.log(i);
|
|||
|
```
|
|||
|
|
|||
|
У такому разі консоль показуватиме значення `[0, 1, 2]` та `3`.
|
|||
|
|
|||
|
Якщо ключове слово — `var`, значення `i` оголошується глобальним. Отже, коли виконується `i++`, глобальна змінна теж оновлюється. Цей код виглядає наступним чином:
|
|||
|
|
|||
|
```js
|
|||
|
var numArray = [];
|
|||
|
var i;
|
|||
|
for (i = 0; i < 3; i++) {
|
|||
|
numArray.push(i);
|
|||
|
}
|
|||
|
console.log(numArray);
|
|||
|
console.log(i);
|
|||
|
```
|
|||
|
|
|||
|
У такому разі консоль показуватиме значення `[0, 1, 2]` та `3`.
|
|||
|
|
|||
|
Така поведінка спричиняє проблеми при створенні функції та її збереженні для подальшого використання в циклі `for`, що використовує змінну `i`. Це пояснюється тим, що збережена функція завжди посилатиметься на значення оновленої глобальної змінної `i`.
|
|||
|
|
|||
|
```js
|
|||
|
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` мало при створенні функції для циклу. Ключове слово `let` діє інакше:
|
|||
|
|
|||
|
```js
|
|||
|
let printNumTwo;
|
|||
|
for (let i = 0; i < 3; i++) {
|
|||
|
if (i === 2) {
|
|||
|
printNumTwo = function() {
|
|||
|
return i;
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
console.log(printNumTwo());
|
|||
|
console.log(i);
|
|||
|
```
|
|||
|
|
|||
|
У такому разі консоль показуватиме значення `2`, і помилку: `i is not defined`.
|
|||
|
|
|||
|
`i` не визначено (not defined), оскільки змінну не було оголошено в глобальному масштабі. Вона стає оголошеною лише у команді циклу `for`. `printNumTwo()` повернув правильне значення, оскільки було створено три різних змінних `i` з унікальними значеннями (0, 1, та 2) завдяки ключовому слову `let` в рамках команди циклу.
|
|||
|
|
|||
|
# --instructions--
|
|||
|
|
|||
|
Виправте код так, щоб `i`, оголошена в команді `if`, була окремою змінною, на відміну від `i`, оголошеної у першому рядку функції. Не використовуйте у вашому коді ключове слово `var`.
|
|||
|
|
|||
|
Ця вправа створена для того, щоб показати відмінність між тим, як ключові слова `var` і `let` задають можливості оголошеної змінної. При програмуванні схожої функції на ту, що використовувалася у цій вправі, нерідко слід використовувати різні назви для змінних, щоб уникнути плутанини.
|
|||
|
|
|||
|
# --hints--
|
|||
|
|
|||
|
`var` має бути відсутнім у коді.
|
|||
|
|
|||
|
```js
|
|||
|
assert(!code.match(/var/g));
|
|||
|
```
|
|||
|
|
|||
|
Змінна `i`, оголошена в операторі `if`, має дорівнювати рядку `block scope`.
|
|||
|
|
|||
|
```js
|
|||
|
assert(code.match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g));
|
|||
|
```
|
|||
|
|
|||
|
`checkScope()` має повернути рядок `function scope`
|
|||
|
|
|||
|
```js
|
|||
|
assert(checkScope() === 'function scope');
|
|||
|
```
|
|||
|
|
|||
|
# --seed--
|
|||
|
|
|||
|
## --seed-contents--
|
|||
|
|
|||
|
```js
|
|||
|
function checkScope() {
|
|||
|
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;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
# --solutions--
|
|||
|
|
|||
|
```js
|
|||
|
function checkScope() {
|
|||
|
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;
|
|||
|
}
|
|||
|
```
|