Всем привет! В сегодняшней статье Микроблог мы рассмотрим замыкания в JavaScript и то, как их можно использовать для создания фабрик.

Во-первых, зачем изучать эту технику? Что ж, несмотря на то, что многие люди погружаются прямо в такие фреймворки, как React и Angular, всегда полезно понимать фундаментальный ванильный JavaScript, лежащий в основе этих фреймворков. В результате вы сможете делать больше как с поддерживающими вас фреймворками, так и без них. Теперь о замыканиях:

Что такое замыкания?

Хороший вопрос. По своей сути замыкания — это просто вложенная область внутри функции. Они позволяют внутренней функции получать доступ к переменным внешней функции. Супер простой пример будет выглядеть примерно так:

      const addTo = (numberOne) => {
        return (numberTwo) => {
          return numberOne + numberTwo;
        }
      }
      const addToFive = addTo(5);
      const addToTen = addTo(10);
      addtoFive(3); // => 8
      addToTen(3); // => 13

Когда функция addTo вызывается с параметром, она возвращает другую функцию, имеющую доступ к переменной numberOne; эта возвращаемая функция является замыканием. И addToFive, и addToTen имеют свою уникальную область видимости, где переменная numberOne равна 5 и 10 соответственно. В результате при вызове этих функций с параметром 3 они дают ожидаемые результаты 8 и 13. Теперь о фабриках:

Что такое фабрики?

Фабрики обычно используются при тестировании для создания объектов без создания встроенного полного объявления объекта. Простой пример может выглядеть так:

      /* User {
        {string} firstName
        {string} lastName
        {number} age
      }
      const createUser = (userObj) => {
        // create mock user
        let user = {
          firstName: "John",
          lastName: "Doe",
          age: 21
        };
        Object.keys(user).forEach((userKey) => {
        });
        return user;
      }

Это позволяет нам масштабировать наше тестирование, чтобы оно было более релевантным тестам, которые мы выполняем.

      // WITHOUT FACTORY
      const returnsFalseForMinors = () => {
        // irrelevant data in test
        let user = { firstName: "John", lastName: "Doe", age: 17 });
        console.assert(functionToTest(user), false);
      }
      // WITH FACTORY
      const returnsFalseForMinors = () => {
        let user = createUser({ age: 17 });
        console.assert(functionToTest(user), false);
      }

Заводы и закрытия вместе?

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

      // closure and factories, working together
      const removeAndAdd = (remove, add) => {
        return (el) => { 
          el.classList.remove(remove);
          el.classList.add(add);
        }
      }
      // methods generated by the factory for use later
      const leftToCenter = removeAndAdd("left", "center");
      const centerToRight = removeAndAdd("center", "right");
      const rightToCenter = removeAndAdd("right", "center");
      const centerToLeft = removeAndAdd("center", "left");
      // ...
      const movePrev = () => {
        if (currentIndex <= 0) return;
        else {
          centerToRight(images[currentIndex]);
          leftToCenter(images[--currentIndex]); // decrement inline
          labelText.innerHTML = (currentIndex + 1) + "/" + numImages;
          labelTitle.innerHTML = altText[currentIndex];
        }
      }
      const moveNext = () => {
        if (currentIndex + 1 >= numImages) return;
        else {
          centerToLeft(images[currentIndex]);
          rightToCenter(images[++currentIndex]); // increment inline
          labelText.innerHTML = (currentIndex + 1) + "/" + numImages;
          labelTitle.innerHTML = altText[currentIndex];
        }
      }

Как видите, используя замыкание в качестве фабрики функций, я смог избежать повторных вызовов classList каждого элемента, что сделало мой код более читабельным и семантическим в процессе.

Я надеюсь, что этот короткий пост даст вам представление о силе замыканий в JavaScript, и я надеюсь сделать более длинный пост, в котором будут подробно описаны наиболее эффективные способы их использования. Не забудьте подписаться на меня, чтобы получать уведомления, когда этот пост выйдет.

Если вы нашли этот пост полезным, рассмотрите возможность угостить меня кофе. До скорого!

Первоначально опубликовано наhttps://shaile.sh/codes/posts/2020/12/27/javascript-closures-and-factories/.