Инкапсуляция в JavaScript
Вопрос: Я давно видел, как кто-то оборачивает весь свой блок JavaScript в код, похожий на приведенный ниже:
(function() {
// ...
})(this);
У меня есть несколько вопросов:
- Является ли приведенный выше код корректным?
- Каковы преимущества оборачивания всего блока JavaScript в такую конструкцию?
2 ответ(ов)
Да, это верно. Это называется самовызывающееся анонимное функциональное выражение.
В JavaScript переменные имеют либо функциональную область видимости, либо глобальную область видимости. Блоковой области видимости нет. Обертывание вашего кода в самовызывающуюся функцию, как в вашем примере, создает временную локальную область видимости для кода, который выполняется сразу и однократно, не загрязняя глобальную область имен.
Рассмотрите следующий пример:
<html>
<body>
...
<script>
(function() {
var x = '';
function myFunction () {
alert('Hello: ' + x);
}
x = 'Bob';
myFunction();
alert(typeof x); // string
alert(typeof myFunction); // function
})();
alert(typeof x); // undefined
alert(typeof myFunction); // undefined
</script>
<script src="other-javascript.js"></script>
</body>
</html>
Все, что вы объявляете в этой самовызывающейся функции, находится в отдельной области видимости. Переменная x
и функция myFunction()
не могут быть доступны откуда-либо еще. Код в other-javascript.js
не увидит их, например, и будет свободен объявить другую функцию myFunction()
без конфликтов.
На всякий случай, стоит отметить, что ECMA TC39 предложил синтаксис для приватных полей. Согласно этому предложению, чтобы сделать поле класса в JavaScript приватным, нужно добавить перед ним символ решетки #
. Это нужно для обеспечения определенной формы рантайм-инкапсуляции.
Пример:
class B {
#hidden = 0;
m() {
return this.#hidden;
}
}
Поддержка этого синтаксиса была добавлена в Chrome начиная с версии 74. Если этот синтаксис будет принят в стандарт, мы сможем воспользоваться возможностями рантайм-инкапсуляции в JavaScript, а также, вероятно, в TypeScript, поскольку его транспиляция будет обновлена соответствующим образом.
Где найти документацию по форматированию даты в JavaScript?
Как определить нажатие клавиши Esc?
Как проверить, содержит ли массив строку в TypeScript?
Ссылка и выполнение внешнего JavaScript-файла, размещенного на GitHub
Как остановить Babel от трансформации 'this' в 'undefined' и добавления "use strict"