Давным-давно я видел, как кто-то инкапсулировал весь свой блок JavaScript с кодом вроде кода ниже:
(function() {
// ...
})(this);
Вопросы:
- Правильно ли указан код?
- Какая польза от инкапсуляции всего блока JavaScript, как указано выше?
Давным-давно я видел, как кто-то инкапсулировал весь свой блок JavaScript с кодом вроде кода ниже:
(function() {
// ...
})(this);
Вопросы:
Да, это правильно. Он называл самоисключение анонимного выражения функции.
Переменные 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()
без конфликтов.
В дополнение к ответу @Daniel передача this
в функцию - это общий шаблон для ссылки на глобальный объект, например:
(function(window){
})(this);
В сценарии браузера глобальный объект имеет свойство с именем window
, которое относится к самому глобальному объекту, в других средах нет свойства window
.
Кроме того, еще одна вещь, которую можно сделать, - указать аргумент с именем undefined
, поскольку свойство undefined
не описано в ECMAScript 3rd. Standard Edition (нет гарантии, что существуют или нет), а в некоторых реализациях свойство изменено, например:
(function(window, undefined){
})(this);
В приведенном выше примере у нас есть два локальных идентификатора (которые немного быстрее разрешены), window
и undefined
, передается только первый (this
, который всегда ссылается на глобальный объект в Глобальный код (код, который находится вне любой функции)), а второй будет содержать примитивное значение undefined
, потому что мы не проходим мимо любое значение для него.
Этот шаблон используется некоторыми библиотеками, такими как jQuery.
Для справки, ECMA TC39 предложил частный синтаксис. Согласно предложению, для того, чтобы сделать поле класса javascript закрытым, необходимо добавить к нему хеш '#'. Это делается для обеспечения некоторой инкапсуляции во время выполнения.
Пример:
class B {
#hidden = 0;
m() {
return this.#hidden;
}
}
Chrome поддерживает это начиная с Chrome v74. Если этот частный синтаксис станет стандартом, мы сможем извлечь выгоду из инкапсуляции во время выполнения в javascript и, предположительно, в typcript, поскольку его преобразование будет обновлено таким образом.