Паттерн “Модуль”

87
22 января 2018, 09:46

В книжке «Паттерны для масштабируемых JavaScript-приложений» в разделе, где описывается паттерн "Модуль", написано, что модуль, в отличие от IIFE возвращает объект, а не функцию (2-й абзац).

Вопрос в следующем:
Что может вернуть JS-модуль, написанный согласно этому паттерну?
Разве я не могу вернуть, скажем, функцию-конструктор(класс)?
Правильно ли написано в книге об этом паттерне?

Answer 1

Вопрос в том, правильно ли написано в книге об этом паттерне (в частности, во 2-м абзаце)?

Первым делом отвечу на это.

Как мне кажется, нет. Не совсем верно используются термины, что и привело вас в заблуждение. В частности, в этом 2-ом абзаце автор материала сравнивает Модуль как паттерн с IIFE (которые сами по себе не являются паттернами):

Этот паттерн очень похож на немедленно-вызываемые функции (IIFE), за тем исключением, что модуль вместо функции, возвращает объект.

Вообще, это довольно спорное утверждение, что IIFE не являются паттернами. Спецификацией языка они не определены как некая отдельная сущность, и свое название им действительно дало сообщество, из чего можно сделать вывод, что IIFE тоже являются паттерном. Но сейчас не об этом.

Сейчас я говорю о том, что автор статьи сравнивает 2 несравниваемые вещи. IIFE в привычном понимании - это самовызывающаяся функция, которая сама по себе не может ограничивать видимость свойств объекта. Посмотрите на код:

void function() {}();

Это - IIFE. Но где он здесь возвращает функцию, как о нем говорит автор статьи?

А вот модуль:

var basketModule = (function() {
  var basket = []; // приватная переменная
    return { // методы доступные извне
        addItem: function(values) {
            basket.push(values);
        },
        getItemCount: function() {
            return basket.length;
        },
        getTotal: function() {
           var q = this.getItemCount(),p=0;
            while(q--){
                p+= basket[q].price; 
            }
            return p;
        }
    }
}());

И в результате исполнения этого кода переменная basketModule действительно будет содержать объект.

У меня есть 2 варианта того, почему автор привел такое некорректное сравнение:

  1. IIFE - это, в рамках его статьи, название какого-то другого паттерна, а не тот IIFE, о котором мы с вами говорим.

  2. Автор просто ошибся в формулировке мыслей.

Вообще, насколько я понимаю, автор хотел сравнить паттерн модуль с другим известным паттерном (сейчас не вспомню его название), который определяет конструктор объекта, а не сам объект в отдельности. Тут важно понимать, что само слово "Модуль" говорит о том, что полученный в результате объект уже является чем-то готовым, что можно, например, примешать (как модуль) к чему-нибудь.

А вот пример того известного паттерна, о котором говорил я:

let Constructor = (function() {
    let private = "Какое-нибудь приватной свойство (по сути, просто локальная переменная)";
    return function() {
        // к которой можно обратиться при помощи замыкания внутри конструктора. 
    }
}());

То есть в отличии от Модуля, здесь мы не получаем сразу какой-то готовый объект со скрытыми свойствами, а получаем конструктор, позволяющий генерировать объекты (тоже с приватными свойствами).

Вероятно, эти 2 вещи и приводил в сравнение автор вашей статьи.

Подведу итог

Описанный в статье паттерн модуль подразумевает на выходе готовый объект, с которым уже можно как-то оперировать. Например, мы можете создать модуль Movable и при помощи Object.assign(), например, "примешать" его к какому-нибудь своему объекту, чтобы добавить вашему объекту функции, определенные этим модулем.

А IIFE, с которым его сравнивает автор, на самом деле не IIFE само по себе, а (как я предполагаю), совершенно другой паттерн, который при помощи все тех же (настоящих) IIFE позволяет реализовать своего рода приватные свойства на уровне конструктора (или прототипа объекта, см. комментарий).

READ ALSO
Кнопка очистки всех полей формы

Кнопка очистки всех полей формы

Есть обычная формаЗначения сохраняются в сессии и не удаётся её очистить при помощи стандартного <input type="reset" />

71
timeout between dbclick and click events

timeout between dbclick and click events

У меня есть два ивента на одном и том же объекте(видео) с функциями:

52
Очистка формы javascript

Очистка формы javascript

Есть кнопка, которая очищает конкретное поле формы, вот она:

80
Бегущая строка без использования тега &lt;marquee&gt;

Бегущая строка без использования тега <marquee>

Как можно создать бегущую строку на javascript? Текст, который надо показывать предварительно вводится пользователем и потому может быть любой...

60