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

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

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

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

person nerdess    schedule 29.01.2012    source источник


Ответы (4)


Здесь происходит несколько вещей. Во-первых, это шаблон немедленно вызываемого функционального выражения (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;

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

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.

person Howard    schedule 29.01.2012
comment
Очень хорошо поставлено объяснение. Кроме того, в качестве примечания я видел, как Дуглас Крокфорд упомянул в своем выступлении, что он предпочитает (function() {}()); эффективно обернуть весь IIFE в скобки для ясности - более выразительно. - person GuiDoody; 06.06.2014
comment
по сравнению со ссылкой на вики скобки обертывают все это, имеет ли это какое-то значение? - person James Lin; 25.06.2015
comment
Итак, в (function(x){ delete x; return x; })(1); delete x не имеет никакого эффекта, верно? Потому что x — это переменная, а не свойство. Следовательно, delete x не имеет никакого эффекта, верно? - person Utku; 09.12.2016
comment
@Утку да, точно - person Howard; 17.02.2017

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

Это точно так же, как:

function foo(x) {
    delete x;
    return x;
}
foo(1);
person xdazz    schedule 29.01.2012
comment
Я бы использовал var foo = function(){}, чтобы не путать операторы функций и функциональные выражения. - person hugomg; 29.01.2012
comment
@missingno Они одинаковы. - person xdazz; 29.01.2012

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

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

person dmp    schedule 29.01.2012

Люди обычно называют это «немедленно вызываемыми функциональными выражениями» или «самоисполняемыми функциями».

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

person hugomg    schedule 29.01.2012