Модули через замыкания в JavaScript

Описанная выше проблема характерна для любого языка программирования. В качестве решения применяют так называемые модули.

Модуль представляет собой некую конструкцию, сделанную так, чтобы переменные и функции этой конструкции были видны только внутри нее и не мешали никому снаружи.

В JavaScript существуют несколько типов модулей. Самые простые модули через замыкания создаются с помощью вызова функции на месте, вот так:

;(function() { // тут код модуля })();

Переменные и функции, созданные в таком модуле, не будут видны снаружи этого модуля:

;(function() { let str = 'переменная модуля'; function func() { alert('функция модуля'); } })(); // Тут переменные и функции модуля недоступны: alert(str); alert(func);

Практическое применение

Пусть у нас даны два дива с числами:

<div id="div1">10</div> <div id="div2">10</div>

Давайте сделаем так, чтобы по клику по первому диву его значение возводилось в квадрат, а по клику по второму диву - в куб.

Организуем наш код в виде двух модулей:

;(function() { let elem = document.querySelector('#div1'); // первый див function func(num) { return num * num; // возведем в квадрат } elem.addEventListener('click', function() { this.textContent = func(elem.textContent); }); })(); ;(function() { let elem = document.querySelector('#div2'); // второй див function func(num) { return num * num * num; // возведем в куб } elem.addEventListener('click', function() { this.textContent = func(elem.textContent); }); })();

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

Например, оба элемента мы храним в переменной elem - каждый в своей переменной своего модуля.

Если бы модулей здесь не было, пришлось бы вводить разные переменные для хранения наши элементов.

А с модулями мы можем спокойно использовать переменную elem, не боясь того, что кто-то захочет также использовать эту переменную.

То же самое можно сказать и про функцию func - в обоих модулях есть функция с таким именем и, если бы модулей не было, пришлось бы им давать разные имена.