Приложение на лексикалната среда на функции в JavaScript

Да предположим, че имаме функция, която връща друга функция като резултат:

javascriptfunction test() {
  return function() {
    
  }
}

Ако родителската функция има някакви променливи, тези променливи ще се съдържат в лексикалната среда на върнатата функция:

javascriptfunction test() {
  let num = 1; // променлива на родителската функция
  
  return function() {
    // лексикална среда = {num: 1}
  }
}

Нека напишем в кода на нашата върната функция console.log, който извежда стойността на променливата num:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    console.log(num);
  }
}

Сега нека извикаме родителската функция test и запишем резултата от работата й в променлива func:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    console.log(num);
  }
}

let func = test();

В променливата func ще се запише върнатата функция. Нека извикаме нашата функция - като резултат тя ще изведе съдържанието на променливата num:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    console.log(num);
  }
}

let func = test();
func(); // ще изведе 1

Ако просто се опитаме да изведем променливата num извън функцията - тя няма да бъде достъпна:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    console.log(num);
  }
}

console.log(num); // променливата num тук не е достъпна

Както виждате, локалната променлива num се свърза с лексикалната среда на нашата функция и сега, като извикаме тази функция навсякъде в кода, можем да получим стойността на променливата num, дори ако на мястото на извикване самата променлива е недостъпна.

Всъщност може да се постигне подобен резултат, като направим променливата num глобална:

javascriptfunction test() {
  return function() {
    console.log(num);
  }
}

let num = 1; // глобална променлива
let func = test();
func(); // ще изведе 1

Тук обще ще има съществена разлика: в новата версия променливата num може да се променя извън функциите (тъй като е глобална), а в старата - не.

Задание 1

Определете, без да стартирате кода, какво ще се изведе в конзолата:

javascriptfunction test() {
  let num1 = 1;
  let num2 = 2;
  
  return function() {
    return num1 + num2;
  }
}

let func = test();
console.log(func());
Задание 2

Определете, без да стартирате кода, какво ще се изведе в конзолата:

javascriptfunction test() {
  let num1 = 1;
  let num2 = 2;
  
  return function() {
    return num1 + num2;
  }
}

console.log(test()());
Задание 3

Определете, без да стартирате кода, какво ще се изведе в конзолата:

javascriptfunction test() {
  let num1 = 1;
  
  return function() {
    return num1 + num2;
  }
}

let num2 = 2;
let func = test();
console.log(func());
Задание 4

Определете, без да стартирате кода, какво ще се изведе в конзолата:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    return num;
  }
}

let num = 2;
let func = test();
console.log(func());