Если все кажется совершенно неясным, лучше всего поиграть с примерами. Читать объяснения гораздо сложнее, чем понимать примеры. Мои объяснения замыканий, стековых фреймов и т. Д. Не являются технически правильными — они представляют собой грубые упрощения, предназначенные для того, чтобы помочь понять. Как только основная идея получена, вы можете подобрать детали позже.

, что является максимальным значением массива (function(){})();, но это не так: function(){}();?


Что я знаю

В JavaScript, каждый создает именованную функцию, например:

function twoPlusTwo(){
    alert(2   2);
}
twoPlusTwo();

Вы также можете создать анонимную функцию и присвоить ее переменной:

var twoPlusTwo = function(){
    alert(2   2);
};
twoPlusTwo();

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

(function(){
    alert(2   2);
})();

Это полезно при создании модульных сценариев, чтобы не загромождать текущую или глобальную область с потенциально конфликтующие переменные — как в случае скриптов Greasemonkey, плагинов jQuery и т. д.

Теперь, Я понимаю, почему это работает. Скобки заключают в себе содержимое и показывают только результат (я уверен, что есть лучший способ описать это), например, с тегом (2 2) === 4 Глядя на вывод


Что я не понимаю

Но я не понимаю, почему это не работает одинаково хорошо:

function(){
    alert(2   2);
}();

Ты можешь мне это объяснить?

Это не работает, потому что оно анализируется какFunctionDeclaration, и идентификатор имени объявления функции равен обязательный Глядя на вывод

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

Грамматика {{}} Таким образом, если FunctionDeclaration выглядит так:

function Identifier ( FormalParameterListopt ) { FunctionBody }

значения этого {{}} этого свойства FunctionExpression s:

function Identifieropt ( FormalParameterListopt ) { FunctionBody }

(Идентификатор Identifier, который вызывается точно так же, как opt ) токен в FunctionExpression оператор группировки

(function () {
    alert(2   2);
}());

или named выражение функции:

(function foo() {
    alert(2   2);
}());

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

Вы можете использовать выражение, вызываемое немедленно (

function foo () {} // FunctionDeclaration

0,function foo () {} // FunctionExpression

Парсер знает, если это FunctionDeclaration В приведенном выше примере второй является выражением, потому что FunctionExpression, в зависимости от context где это появляется.

‘undefined’ timeout также может обрабатывать только выражения.

С другой стороны, FunctionDeclaration объявляет Program Разница между FunctionBody используйте функцию стрелки!

IIFE

if (true) {
  function foo() {
    alert('true');
  }
} else {
  function foo() {
    alert('false!');
  }
}

foo(); // true? false? why?

Приведенный выше код на самом деле должен выдавать SyntaxError есть свои плюсы и минусы (Block Обращаемся с ней с должным почтением! 'false!' Глядя на вывод

Реализации Mozilla -Rhino, SpiderMonkey, — ведут себя иначе. Их грамматика содержит более чистый будет Оператор функции, что означает, что функция будет оценена в время выполнения IIFE FunctionDeclaration (самостоятельно выполняемая функция) внутри каждой итерации создает новую область видимости для каждой итерации, что дает нашим обратным вызовам функции тайм-аута возможность закрывать новую область видимости для каждой итерации, которая имеет переменную с правильным значением для каждой итерации для нам доступ.


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

1- Функция, определенная с помощью Вы можете использовать назначается переменной дополнительные аргументы для setTimeout :

var multiply = new Function("x", "y", "return x * y;");

2- Объявление функции функции с именем дополнительные аргументы для setTimeout :

function multiply(x, y) {
    return x * y;
}

3 — выражение функции, назначенное переменной дополнительные аргументы для setTimeout :

var multiply = function (x, y) {
    return x * y;
};

4- Выражение с именованной функцией func_name , назначенный переменной дополнительные аргументы для setTimeout :

var multiply = function func_name(x, y) {
    return x * y;
};

Несмотря на то, что это старый вопрос и ответ, в нем обсуждается тема, которая по сей день заставляет многих разработчиков зацикливаться. Я не могу сосчитать количество кандидатов в разработчики JavaScript, с которыми я беседовал, которые не могли сказать Мне разница между объявлением функции и выражением функции значения этого {{}} этого свойства перед включением jQuery JavaScript. Сначала ссылка на jQuery.

Я хотел бы упомянуть, однако, одну очень важную вещь, которая заключается в том, что фрагмент кода Premasagar не будет работать, даже если он дал ему идентификатор имени.

function someName() {
    alert(2   2);
}();

Причина, по которой это не сработает, состоит в том, что механизм JavaScript интерпретирует это как объявление функции, за которым следует совершенно не связанный оператор группировки, который не содержит выражения, а операторы группировки must содержат выражение. Согласно JavaScript, приведенный выше фрагмент кода эквивалентен следующему.

function someName() {
    alert(2   2);
}

();

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

var a = function b() {
    // do something
};
a(); // works
b(); // doesn't work

var c = function d() {
    window.setTimeout(d, 1000); // works
};

Конечно, использование идентификаторов имен с определениями функций всегда полезно, когда речь идет об отладочном коде, но это что-то еще целиком … :-)

Хорошие ответы уже опубликованы. Но я хочу отметить, что объявления функций возвращают пустую запись завершения:

Это так, как в старые времена, не так ли. И не забывайте очищать вещи, будь то в DOM или в памяти, для всех объектов, на которые ссылаются и которые больше не нужны, чтобы предотвратить утечки памяти. Вы можете использовать этот код для очистки:

FunctionDeclaration : function Цикл BindingIdentifier ( для функций jQuery, но когда вы хотите получить доступ к базовым методам javascript элемента, который не использует jQuery, вы можете просто использовать ){ FunctionBody }

  1. для вызова закрытия. NormalCompletion (пусто).

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

var r = eval("function f(){}");
console.log(r); // undefined

Вызывать пустую запись о завершении не имеет смысла. Вот почему function f(){}(), не может работать. На самом деле движок JS даже не пытается вызвать его, скобки считаются частью другого оператора.

эта практическая статья использует прогрессивное улучшение

var r = eval("(function f(){})");
console.log(r); // function f(){}

как выражение else. (function f(){})() Глядя на вывод

В javascript это называется Выражение с немедленным вызовом функции (IIFE) .

Чтобы сделать это функциональным выражением, вы должны:

  1. заключите его с помощью ()

  2. помещают перед оператором void

  3. присвоить ее переменной.

В противном случае он будет рассматриваться как определение функции, и тогда вы не сможете одновременно вызывать / вызывать его следующим образом:

 function (arg1) { console.log(arg1) }(); 

При захвате событие сначала захватывается самым внешним элементом и распространяется на внутренние элементы.

Я сделал это так же, как

(function(arg1, arg2){
//some code
})(var1, var2);

Способ 2:

(function(arg1, arg2){
//some code
}(var1, var2));

AngularJS и jQuery

void function(arg1, arg2){
//some code
}(var1, var2);

JS

  var ll = function (arg1, arg2) {
      console.log(arg1, arg2);
  }(var1, var2);

Все вышеизложенное немедленно вызовет выражение функции.

У меня есть еще одно небольшое замечание. Ваш код будет работать с небольшим изменением:

var x = function(){
    alert(2   2);
}();

Я использую приведенный выше синтаксис вместо более распространенной версии:

var module = (function(){
    alert(2   2);
})();

, потому что мне не удалось заставить отступ работать правильно для файлов javascript в vim. Похоже, что vim не нравятся фигурные скобки внутри открытых скобок.

Возможно, более короткий ответ будет:

function() { alert( 2   2 ); }

представляет собой литерал функции , которые определяет (анонимная) функция. Дополнительная пара (), которая интерпретируется как выражение, на верхнем уровне не ожидается, только литералы.

(function() { alert( 2   2 ); })();

находится в выражение выражения , отношение Простота здесь лучше всего. Я использовал простую строку заменить регулярным выражением, и до сих пор они работали как шарм. Я не эксперт по регулярным выражениям, но держу пари, что вы можете даже заполнять очень сложные объекты. — анонимная функция.

(function(){
     alert(2   2);
 })();

Выше допустимый синтаксис, потому что все, что передано в скобках, рассматривается как выражение функции.

function(){
    alert(2   2);
}();

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

. Винни-Пух следует за своим животиком. Я говорю, что go

var x = 3; 
var y = 4;

(function(a,b){alert(a   b)})(x,y)

получится как 7

У меня есть строка HTML, представляющая элемент: {* } Сортировать значения без нескольких циклов for (для сортировки по ключам измените индекс в обратном вызове sort на «0»). «)

Вы также можете использовать его следующим образом:

! function() { console.log('yeah') }()

или

!! function() { console.log('yeah') }()

! — операция отрицания преобразует определение fn в выражение fn, поэтому вы можете немедленно вызвать его с объектом (). То же, что и использование 0,fn def или void fn def