
Всем привет. Сегодня мы с вами разберем, что такое паттерн модуль в javascript и как реализовывать приватные методы и свойства у обьектов с его помощью.
Для начала давайте напишем
var counter = 0;
Как мы понимаем, это у нас будет переменная window. И напишем два метода Один называется increaseCounter, который будет увеличивать наш counter
var increaseCounter = function () {
counter++;
}
а второй метод назовем getCounter
var getCounter = function () {
return counter;
}
который будет возвращать нам наш счетчик.
Если мы запустим этот код, то у нас есть функция
increaseCounter()
которая увеличивает счетчик. И
getCounter()
которая вернула нам 1.
Но переменная counter лежит у нас в window и она доступна для изменения в любой момент времени. На самом деле, это очень плохо, поскольку любой другой разработчик может случайно поменять эту переменную, даже не подозревая об этом. Допустим он напишет
counter = 'gewgewgwe';
и присвоит в counter строку. Тогда, когда мы в следующий раз будем выполнять
increaseCounter()
getCounter()
то мы увидим, что у нас наш результат уже работает некорректно. И у нас в консоли выводится NaN.
Как от этого избавиться? И причем здесь модульность? Когда мы используем модуль, мы делаем анонимную функцию, которая позволяет нам хранить все данные, которые нам необходимы внутри нее. И делать для нее простой публичный API. Давайте попробуем.
var counterModule = (function () {
var counter = 0;
var increaseCounter = function () {
counter++;
}
var getCounter = function () {
return counter;
}
})();
В counterModule присвоим анонимную самомызывающуюся функцию и перенесем весь наш код внутрь.
Теперь давайте вернем два метода getCounter и increaseCounter.
return {
getCounter: getCounter,
increaseCounter: increaseCounter
}
Если мы попробуем теперь вывести counterModule, то это обьект, который возвращает нам getCounter и increaseCounter. Если же мы вызываем increaseCounter, то getCounter нам потом возвращает 1, увеличивая наш counter на столько, сколько раз мы его вызовем. Никакого доступа к counter у нас нет. Как мы видим, в window у нас counter тоже нет. И в counterModule counter нам тоже недоступен.
Поэтому никто теперь не может поменять нам counter и наш код всегда будет работать правильно. Когда вы изолируете, таким образом, свои функции и обьекты, то вы делаете модуль. И тогда можно не боятся, что ваш код поломается.
Второй плюс модуля - это жесткое указание его зависимостей. Вот у меня в index.html подключена библиотека jQuery. Она нам доступна сейчас в консоли. Допустим, у нас у нашего counterModule будет зависимость от jQuery. Для этого мы просто передаем jQuery в качестве одного из параметров в наш counterModule.
var counterModule = (function () {
var counter = 0;
var increaseCounter = function () {
counter++;
}
var getCounter = function () {
return counter;
}
})(jQuery);
И тогда внутри функции первым параметром мы можем задать что угодно.
var counterModule = (function (jQ) {}())
Что это нам дает? Мы жестко указываем, что наш модуль зависит от jQuery. Мы ему передаем jQuery первым параметром и потом мы можем его определить как угодно. Потом мы можем работать внутри модуля с другим названием, например, jQ. Или вам не нравится $, потому что эту переменную вы уже заняли. Например вы можете внутри написать
console.log(jQ('body'));
И мы видим, что jQuery нашел нам наш елемент body. Это вторая вещь, почему стоит использовать модуль.