Расширенный JavaScript: почему эта функция заключена в круглые скобки?

Возможный дубликат:
Что представляет собой функция (function() {})() в JavaScript?

Я натолкнулся на этот бит кода JavaScript, но я понятия не имею, что из этого сделать. Почему я получаю "1", когда запускаю этот код? Что это за странное небольшое приложение (1) и почему функция заключена в круглые скобки?

(function(x){
    delete x;
    return x;
})(1);

Ответ 1

Здесь есть несколько вещей. Сначала это шаблон, выведенный сразу же выражение функции {IIFE):

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

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

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

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

Этот синтаксис недействителен:

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

Потому что вам нужно обернуть функцию в круглые скобки, чтобы заставить ее анализировать как выражение. Более подробная информация здесь: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Итак, быстро перейдем к шаблону IIFE:

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

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

Вы можете передавать аргументы своей функции так же, как и обычную функцию, например

(function(x) {
  // Some code
})(1);

Итак, мы передаем значение "1" в качестве первого аргумента функции, которое получает его как переменную с локальным охватом, называемую x.

Во-вторых, у вас есть кишки самого кода функции:

delete x;
return x;

Оператор delete удаляет свойства из объектов. Он не удаляет переменные. Таким образом,

var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);

Результаты регистрации этого файла:

{'baz':5}

В то время,

var foo = 4;
delete foo;
console.log(foo);

будет записывать значение 4, потому что foo - это переменная, а не свойство, поэтому ее нельзя удалить.

Многие полагают, что delete может удалить переменные из-за того, как работают автоглавы. Если вы назначаете переменную без объявления ее сначала, она фактически не станет переменной, а является свойством глобального объекта:

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.

На этот раз удаление работает, потому что вы не удаляете переменную, а свойство на глобальном объекте. Фактически предыдущий фрагмент эквивалентен этому:

window.bar = 4;
delete window.bar;
console.log(window.bar);

И теперь вы можете увидеть, как это аналогично примеру объекта foo, а не пример переменной foo.

Ответ 2

Это означает, что вы создали анонимную функцию и вызываете ее с параметром 1.

Это то же самое, что:

function foo(x) {
    delete x;
    return x;
}
foo(1);

Ответ 3

Обычно люди называют эти выражения "Вынужденные функциональные выражения" или "Self Executing Functions".

Дело в том, что переменные, объявленные внутри этой функции, не протекают наружу.

Ответ 4

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

Здесь ссылка MDN для удаления, а ссылка MDN для закрытий, в котором также рассматриваются анонимные функции.