Объем и закрытие JavaScript

Я пытаюсь обдумать закрытие (где-то там шутка) и наткнулся на это:

(function () { /* do cool stuff */ })();

Как это работает? Какова цель помещения функции в скобки? Почему после этого пустые скобки?


person chrisdillon    schedule 10.03.2009    source источник


Ответы (7)


Дело в том, что любые переменные, объявленные в классном материале, не будут созданы в глобальном пространстве имен. Любая функция в javascript создаст такую ​​область. Предположим, у вас есть JavaScript, который вы хотите запустить. Если вы сделаете это:

var b = 1; 
// stuff using b

И в другом коде используется b, он получит ваше оставшееся значение. (Или, что еще хуже, если какой-то другой код устанавливает b перед запуском вашего кода, а затем пытается получить его старое значение позже, вы бы тем временем изменили его.)

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

function a() { 
     var b = 1;
}

a();

И какой-то другой код позже использует b, он не увидит ваши значения, поскольку b является локальным для функции. Проблема, конечно, в том, что вы все еще делаете глобальное имя - в данном случае «a». Итак, нам нужна функция без имени - вот почему вы получаете описанный вами код. Он объявляет функцию без имени, а затем вызывает ее.

К сожалению, нельзя просто сказать:

function() { ... }()

потому что это будет проанализировано как объявление функции statement, а затем как синтаксическая ошибка. Заключив объявление функции в круглые скобки, вы получите функцию выражение, которую затем можно будет вызвать. Вы вызываете его, как любое другое выражение функции (например, a выше), используя второй набор скобок. Например, если функция принимает аргументы, вы должны передать их туда:

(function(a) { ... })(1)
person Jesse Rusak    schedule 10.03.2009

Это создает функцию, вызывает ее и отбрасывает.

Это может быть понятнее, если вы посмотрите на это так:

var throwaway = function(){
    // do cool stuff
};
throwaway();

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

person Matthew Marshall    schedule 10.03.2009
comment
За исключением, конечно, того, что вы конфликтуете с названием вашей функции. - person Jesse Rusak; 10.03.2009
comment
Ага. Вот почему обычно это делается с помощью анонимной функции. Я просто использовал именованную функцию, чтобы показать более знакомую форму, которая делает то же самое. - person Matthew Marshall; 10.03.2009
comment
У jder есть лучший ответ для тех, кто опаздывает на вечеринку. - person Triptych; 10.03.2009
comment
@Peter Bailey - я имею в виду, что переменные внутри throwaway не будут конфликтовать, а вот выбрасывание глобального имени может. - person Jesse Rusak; 10.03.2009
comment
jder расширил мое понимание замыканий, но Мэтью коротко и мило ответил на мои 3 вопроса. Спасибо! - person chrisdillon; 10.03.2009
comment
Никакого неуважения к jder, но его пост не объясняет закрытие - он просто объясняет лексическую область видимости. - person Peter Bailey; 10.03.2009

я недавно наткнулся на этот пост. Этот тип определения и вызова функции называется самозапускающимися функциями.

(function(){  //code })();

Код внутри функции будет выполнен сразу после ее определения.

person Anish    schedule 18.03.2011

Эта конструкция означает объявление анонимной функции и ее немедленный запуск. Причина, по которой вы помещаете свой код в тело функции, заключается в том, что переменные, которые вы определяете внутри него, остаются локальными для функции, а не как глобальные переменные. Однако они по-прежнему будут видны замыканиям, определенным внутри этой функции.

person Chetan S    schedule 10.03.2009

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

Обратите внимание, что у функции нет имени.

person John Saunders    schedule 10.03.2009

Один из подходов к закрытию - передать переменные функции:

(function($, var_1, var_2) {
    // use JQuery, var_1 and var_2 as local variables
})($, var_1, var_2);
person Manolo    schedule 14.08.2015

Помещение объявления функции внутри скобок создает выражение, которое оценивает анонимную функцию внутри. Таким образом, первая скобка означает функцию.

«Пустые скобки» в конце вызывают определенную функцию, поэтому «// делать крутые вещи» выполняется немедленно.

Это способ выполнять код «на лету», при этом сохраняя переменные вне глобальной области видимости.

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

person Peter Bailey    schedule 10.03.2009