Синтаксис замыканий в JS

101
23 ноября 2020, 15:10

Первый раз столкнувшись с замыканиями и не зная, что это такое, пробовал синтаксически понять, что происходит в коде вида: (function(){})(). Известно, что конструкция "()" - это вызов функции. Возникал вопрос по поводу первых круглых скобок

Позже, проникнувшись темой, вопрос первых круглых скобок меня волновать не перестал. Зачем они нужны, если без них всё работает?

При этом ни одного примера в статьях про замыкания без применения первых круглых скобок я не видел.

Классический пример замыкания в JavaScript:

buttons[i].onclick = (function(a){
    return  function(){ console.log(a);}
})(i)

без первых скобок:

buttons[i].onclick = function(a){
         return function(){ console.log(a);}
}(i)

Зачем во всех примерах эти, получается лишние, синтаксические элементы?

Answer 1

Ключевое слово function в js может употребляться в двух контекстах - это контекст объявления функции и контекст выражения, где это слово создает анонимную функцию.

Если строка начинается со слова function - то это объявление функции. С такой функцией нельзя ничего сразу же сделать (например, вызвать), кроме того, у нее должно быть имя.

function (a) { console.log(a) } (5) // Ошибка

Поэтому такую функцию во что-нибудь оборачивают:

+function (a) { console.log(a) } (5) // 5
!function (a) { console.log(a) } (5) // 5
~function (a) { console.log(a) } (5) // 5
(function (a) { console.log(a) }) (5) // 5
(function (a) { console.log(a) } (5)) // 5

Если же слово function стоит не в начале строки - то ничего делать и не надо, все будет прекрасно работать:

var a = function (a) { return 5 } (5)
Answer 2

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

(function(){alert(1);})()
(function(){alert(1);}())
!function(){alert(1);}()
+function(){alert(1);}()

В вашем примере роль круглых скобок выполняет оператор присвоения, поэтому они там действительно не нужны. Обычно используются именно круглые скобки, потому что они не заставляют программу выполнять лишние телодвижения (из примеров выше - приводить функцию к числу или к булевому значению). Они нужны, когда вам не нужно с анонимной функцией ничего делать, кроме её вызова

Answer 3

Конструкции вида:

(function() {
  ...
})();

Это паттерн Immediately-invoked function expression. В JavaScript его принято использовать для разделения области видимости переменных - что бы случайно не наплодить глобальных переменных, которые впоследствии могут вызвать ошибки в других блоках кода.

READ ALSO
непонятно поведение prototype

непонятно поведение prototype

почему код срабатывает лишь в третьем случае

116
select на всю оставшуюся ширину

select на всю оставшуюся ширину

Есть контейнер фиксированной шириныВ нем нужно расположить 3 элемента:

101
Игра - 15 палок. Не могу определить проблему

Игра - 15 палок. Не могу определить проблему

Не знаю как это игра называется на самом деле, но нужно было реализовать это: Реализовать игру 15 палокВы играете с компьютером

133
Удаление созданных с помощью new объектов

Удаление созданных с помощью new объектов

Народ, прошу помощиВроде простой вопрос, но ничего полезного при поиске решения не нашел

117