JavaRush /Курси /Frontend SELF UA /Замикання

Замикання

Frontend SELF UA
Рівень 37 , Лекція 5
Відкрита

6.1 Поняття замикань

Замикання є однією з найбільш потужних і важливих концепцій у JavaScript. Вони дозволяють функціям запам'ятовувати своє лексичне оточення навіть після того, як вони були виконані. У цій лекції ми розглянемо поняття замикань, їх особливості та наведемо різні приклади їх використання.

Замикання (closure) у JavaScript — це комбінація функції та лексичного оточення, у якому ця функція була оголошена. Замикання дозволяє функції "запам'ятовувати" і отримувати доступ до змінних та інших функцій зі своєї зовнішньої області видимості навіть після того, як зовнішня функція була виконана.

Основні властивості замикань:

  1. Лексичне оточення: контекст, у якому була оголошена функція, включаючи всі змінні, доступні на момент оголошення.
  2. Збереження контексту: функція із замиканням може зберегти доступ до змінних із зовнішньої області видимості навіть після завершення виконання цієї зовнішньої функції.

6.2 Приклади роботи замикань

Приклад 1: Просте замикання

У цьому прикладі innerFunction() має доступ до змінної outerVariable зі своєї зовнішньої області видимості навіть після завершення виконання outerFunction().

JavaScript
    
      function outerFunction() {
        let outerVariable = 'Я з зовнішньої функції';

        function innerFunction() {
          console.log(outerVariable);
        }
        return innerFunction;
      }

      const closure = outerFunction();
      closure(); // Виведе: Я з зовнішньої функції
    
  

Приклад 2: Лічильник з використанням замикання

У цьому прикладі функція-лічильник зберігає значення змінної count і збільшує його при кожному виклику.

JavaScript
    
      function createCounter() {
        let count = 0;

        return function() {
          count++;
          return count;
        };
      }

      const counter = createCounter();

      console.log(counter()); // Виведе: 1
      console.log(counter()); // Виведе: 2
      console.log(counter()); // Виведе: 3
    
  

Приклад 3: Замикання в циклі

Замикання часто використовуються для збереження значень змінних у циклах.

У цьому прикладі кожна функція всередині масиву arr "запам'ятовує" значення змінної i у момент свого створення завдяки блочній області видимості let:

JavaScript
    
      function createArrayWithClosures() {
        let arr = [];

        for (let i = 0; i < 3; i++) {
          arr[i] = function() {
            console.log(i);
          };
        }
        return arr;
      }

      const closures = createArrayWithClosures();

      closures[0](); // Виведе: 0
      closures[1](); // Виведе: 1
      closures[2](); // Виведе: 2
    
  

6.3 Складні сценарії використання замикань

Приклад 1: Часткове застосування функції (partial application)

Замикання дозволяють створювати частково застосовані функції, зберігаючи деякі аргументи фіксованими.

У цьому прикладі функція multiply() повертає функцію, яка множить переданий їй аргумент b на зафіксований аргумент a.

JavaScript
    
      function multiply(a) {
        return function(b) {
          return a * b;
        };
      }

      const double = multiply(2);
      console.log(double(5)); // Виведе: 10
      console.log(double(10)); // Виведе: 20
    
  

Приклад 2: Приховування даних (data hiding)

Замикання можуть використовуватися для створення приватних змінних та методів.

У цьому прикладі змінні _name і _age є приватними та доступні лише через методи об'єкта:

JavaScript
    
      function createPerson(name, age) {
        let _name = name;
        let _age = age;

        return {
          getName: function() {
            return _name;
          },
          getAge: function() {
            return _age;
          },
          setName: function(newName) {
            _name = newName;
          },
          setAge: function(newAge) {
            _age = newAge;
          }
        };
      }

      const person = createPerson('Джон', 30);
      console.log(person.getName()); // Виведе: Джон

      person.setName('Джейн');

      console.log(person.getName()); // Виведе: Джейн
      console.log(person.getAge());  // Виведе: 30
    
  

Приклад 3: Мемоізація

Мемоізація — це техніка оптимізації, при якій результати функції зберігаються, щоб уникнути повторних обчислень для однакових вхідних даних.

У цьому прикладі функція memoize() використовує замикання для збереження кешу обчислених результатів функції fn():

JavaScript
    
      function memoize(fn) {
        const cache = {};

        return function(...args) {
          const key = JSON.stringify(args);
          if (cache[key]) {
            return cache[key];
          }
          const result = fn(...args);
          cache[key] = result;
          return result;
        };
      }

      function slowFunction(num) {
        console.log('Обчислення...');
        return num * 2;
      }

      const memoizedFunction = memoize(slowFunction);

      console.log(memoizedFunction(5)); // Виведе: Обчислення... 10
      console.log(memoizedFunction(5)); // Виведе: 10 (результат взято з кешу)
    
  
1
Опитування
Date, Timer і літерали, рівень 37, лекція 5
Недоступний
Date, Timer і літерали
Date, Timer і літерали
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ