Files

5.4 KiB
Raw Permalink Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
587d7b87367417b2b2512b40 Порівняйте можливості ключових слів var та let 1 301195 compare-scopes-of-the-var-and-let-keywords

--description--

Якщо ви ще не знаєте про let, то перегляньте це завдання.

Коли ви задаєте змінну з ключовим словом var, вона стане глобальною або локальною, якщо буде оголошена у рамках функції.

Ключове слово let функціонує схожим чином, але з додатковими можливостями. Коли ви задаєте змінну з ключовим словом let у блоці, команді чи виразі, її можливості обмежуються цим блоком, виразом чи виразом.

Наприклад:

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++, глобальна змінна теж оновлюється. Цей код виглядає наступним чином:

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.

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 діє інакше:

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 має бути відсутнім у коді.

assert(!code.match(/var/g));

Змінна i, оголошена в операторі if, має дорівнювати рядку block scope.

assert(code.match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g));

checkScope() має повернути рядок function scope

assert(checkScope() === 'function scope');

--seed--

--seed-contents--

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--

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;
}