Простая функция JavaScript с немедленным вызовом не работает... почему?

Может кто-нибудь объяснить, почему это работает:

var sayHello = function (name) {
   alert("Hello there " + name + "!");
}("Mike");

Пока это не так:

function sayHello (name) {
   alert("Hello there " + name + "!");
}("Mike");

Майк Торт

+3
источник поделиться
6 ответов

Все, что вам нужно понять, это различие между FunctionExpressions и FunctionDeclarations в Javascript.

Когда вы окружаете функцию с помощью скобок -

(function sayHello (name) {
   alert("Hello there " + name + "!");
})("Mike");

- вы, технически, примените к нему оператора группировки. После применения общее производство больше не является FunctionDeclarataion, а является FunctionExpression. Сравнить -

function foo(){ } // FunctionDeclaration

(function foo(){ }); // FunctionExpresson
typeof function(){ }; // FunctionExpression
new function(){ }; // FunctionExpression

Выражение FunctionExpression (в отличие от FunctionDeclaration), как и любой другой MemberExpresson, можно добавить с помощью Arguments ( "(" и ")" ) и приведет к вызову функции. Именно поэтому функция вызывается в первом примере, а не через секунду.

Обратите внимание, что в FunctionExpressions разрешено иметь необязательные идентификаторы (в отличие от FunctionDeclarations, которые всегда должны иметь один), поэтому вы можете легко опустить "sayHello" и в итоге получить так называемое выражение анонимной функции -

(function(){
  alert('...');
});

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

+13
источник

Второй код на самом деле:

function sayHello (name) {
   alert("Hello there " + name + "!");
}

("Mike");

Итак, вы сначала объявляете функцию "sayHello", а затем выполняете "инструкцию":

("Mike");

который ничего не делает.

+4
источник

Это будет работать:

    (function sayHello (name) {
        alert("Hello there " + name + "!");
     })("Mike");

Обратите внимание на то, что parens обертывают сама функция. Вы также можете удалить имя функции "sayHello", и оно все равно будет работать. Что до чего? Я не уверен. Возможно, это, назначив его переменной и не используя wrapping(), вы на самом деле назначаете ее sayHello, а затем выполняете поздороваться, а не анонимную функцию.

+3
источник
var sayHello = function (name) {
   alert("Hello there " + name + "!");
}("Mike");

Это создает анонимную функцию и вызывает ее сразу с параметром "Майк". Тогда возвращаемое значение этого вызова функции назначается переменной sayHello.

function sayHello (name) {
   alert("Hello there " + name + "!");
}("Mike");

Это просто определяет нормальную функцию с именем sayHello, и оператор функции заканчивается после закрытия}. Затем следует утверждение ( "Майк" ), которое действительно, но ничего не делает.

+1
источник

Отредактировано, потому что мой ответ неправильно прочитал исходное сообщение:

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

(function sayHello (name) {
   alert("Hello there " + name + "!");
})('Mike');
0
источник

Включение определения функции в () перед вызовом:

(function sayHello(name) {
   alert("Hello there " + name + "!");
})("Mike");

// however -- 
alert(typeof sayHello);  // undefined

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

(function(name) {
   alert("Hello there " + name + "!");
})("Mike");

И я не уверен, что это необходимо, но для безопасности - в любое время, когда я использую закрытие, я всегда обертываю его в ()

0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос