Зачем вам нужно вызывать анонимную функцию в той же строке?

ListView также должен автоматически отображать вертикальную полосу прокрутки, если у вас есть достаточно элементов в коллекции (т. е. больше, чем может отображаться в ListView в настоящее время).

368
задан Save 26 July 2015 в 15:23
поделиться

19 ответов

Удалите точку с запятой после определения функции.

(function (msg){alert(msg)})
('SO');

Выше должно работать.

Страница демонстрации: https://jsfiddle.net/e7ooeq6m/

Я обсуждал этот тип паттерна в этом посте:

jQuery и $ questions

РЕДАКТИРОВАТЬ:

Если вы посмотрите спецификацию сценария ECMA , есть 3 способа определения функции. (Стр. 98, раздел 13 «Определение функций»)

1. Использование конструктора функций

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. Использование объявления функций.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. Выражение функции

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

Итак, вы можете спросить, в чем разница между объявлением и выражением?

Из спецификации сценария ECMA:

FunctionDeclaration: идентификатор функции (FormalParameterListopt) {FunctionBody}

FunctionExpression: функция Identifieropt (FormalParameterListopt) {FunctionBody} [Function27]

Если вы заметили, «идентификатор» является необязательным для выражения функции. И когда вы не даете идентификатор, вы создаете анонимную функцию. Это не значит, что вы не можете указать идентификатор.

Это означает, что следующее действительно.

var sum = function mySum(a, b) { return a + b; }

Важно отметить, что вы можете использовать 'mySum' только внутри тела функции mySum, а не снаружи. Смотрите следующий пример:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

Live Demo

Сравните это с

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

Вооружившись этими знаниями, давайте попробуем проанализируйте ваш код.

Когда у вас есть подобный код,

    function(msg) { alert(msg); }

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

    (function(msg) { alert(msg); })('SO'); //alerts SO.
375
ответ дан 13 revs, 4 users 96% 26 July 2015 в 15:23
поделиться
  1. Анонимные функции - это функции, которые динамически объявляются во время выполнения. Их называют анонимными функциями, потому что им не дают имя так же, как обычным функциям.

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

    Вот типичный пример именованной функции:

    function flyToTheMoon () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon (); Вот тот же пример, созданный как анонимная функция:

    var flyToTheMoon = function () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon ();

    Подробнее см. здесь:

    http://helephant.com/2008/08/23/javascript-anonymous-functions/

0
ответ дан Harikesh Yadav 26 July 2015 в 15:23
поделиться

Под анонимными функциями подразумевается одноразовая сделка, в которой вы определяете функцию на лету, чтобы она генерировала выходные данные из предоставленных вами входных данных. За исключением того, что вы не предоставили вход. Вместо этого вы написали что-то во второй строке («SO»); - независимое утверждение, которое не имеет ничего общего с функцией. Что ты ожидал? :)

-1
ответ дан Vietnhi Phuvan 26 July 2015 в 15:23
поделиться

Простая причина, по которой это не работает, не в том, что ; указывает на конец анонимной функции. Это потому, что без () в конце вызова функции, это не вызов функции. То есть

function help() {return true;}

Если вы вызываете result = help();, это вызов функции и она возвращает true.

Если вы звоните result = help;, это не звонок. Это задание, в котором помощь рассматривается как данные, которые должны быть присвоены результату.

То, что вы сделали, объявили / создали экземпляр анонимной функции, добавив точку с запятой,

(function (msg) { /* Code here */ });

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

('SO');

Интерпретатор видит круглые скобки во второй строке как новую инструкцию / инструкцию, и поэтому он не работает, даже если вы сделали это так:

(function (msg){/*code here*/});('SO');

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

(function (msg){/*code here*/})        // This space is ignored by the interpreter
('SO');

Вывод: вызов функции не является вызовом функции без конца () в конце, если только при определенных условиях, например, при вызове другой функции, то есть onload = 'help' не выполнит функцию справки даже хотя скобки не были включены. Я полагаю, что setTimeout и setInterval также разрешают этот тип вызова функции, и я также считаю, что интерпретатор в любом случае добавляет скобки за кулисы, что возвращает нас к «вызову функции не является вызовом функции без скобок».

0
ответ дан Peter Mortensen 26 July 2015 в 15:23
поделиться

Другая точка зрения

Сначала вы можете объявить анонимную функцию:

var foo = function(msg){
 alert(msg);
}

Затем вы вызываете ее:

foo ('Few');

Потому что foo = function (msg) {alert (msg);} , чтобы вы могли заменить foo на:

function(msg){
 alert(msg);
} ('Few');

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

(function(msg){
 alert(msg);
}) ('Few');

Таким образом, это легко понять для меня.

0
ответ дан capu 26 July 2015 в 15:23
поделиться

Когда вы сделали:

(function (msg){alert(msg)});
('SO');

Вы завершили функцию до ('SO') из-за точки с запятой. Если вы просто напишите:

(function (msg){alert(msg)})
('SO');

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

Рабочий пример: http://jsfiddle.net/oliverni/dbVjg/

0
ответ дан Oliver Ni 26 July 2015 в 15:23
поделиться

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

(function forInternalOnly(){

  //you can use forInternalOnly to call this anonymous function
  /// forInternalOnly can be used inside function only, like
  var result = forInternalOnly();
})();

//this will not work
forInternalOnly();// no such a method exist
3
ответ дан xanatos 26 July 2015 в 15:23
поделиться

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

var msg = "later dude";
window.onunload = function(msg){
  alert( msg );
};

Вы можете присвоить пространству имен ваше свойство msg, используя Шаблон модуля раскрытия , например:

var myScript = (function() {
    var pub = {};
    //myscript.msg
    pub.msg = "later dude";
    window.onunload = function(msg) {
        alert(msg);
    };
    //API
    return pub;
}());
0
ответ дан Ron Royston 26 July 2015 в 15:23
поделиться
(function (msg){alert(msg)})
('SO');

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

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

Если поместить ; в первую строку, компилятор обрабатывает его как две разные строки. Таким образом, вы не можете получить те же результаты, что и выше.

Это также может быть записано как:

(function (msg){alert(msg)}('SO'));

Для более подробной информации, посмотрите в JavaScript / анонимные функции .

0
ответ дан Peter Mortensen 26 July 2015 в 15:23
поделиться

Это называется само-вызываемой функцией.

То, что вы делаете, когда вызываете (function(){}), возвращает функциональный объект. Когда вы добавляете () к нему, он вызывается, и все в теле выполняется. ; обозначает конец оператора, поэтому второй вызов завершается неудачей.

126
ответ дан the12 26 July 2015 в 15:23
поделиться

Мое понимание вопроса Аскера таково:

Как работает эта магия:

(function(){}) ('input')   // Used in his example

Я могу ошибаться. Тем не менее, обычная практика, с которой знакомы люди:

(function(){}('input') )

Причина в том, что скобки JavaScript AKA () не могут содержать операторов, и когда парсер встречает ключевое слово function, он знает, анализировать его как выражение функции, а не как объявление функции.

Источник: запись в блоге Выражение функции, вызванной немедленно (IIFE)

3
ответ дан Peter Mortensen 26 July 2015 в 15:23
поделиться

Одна вещь, которую я нашел сбивающей с толку, это то, что "()" - это операторы группировки.

Вот ваша основная объявленная функция.

Пр. 1:

var message = 'SO';

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

foo(message);

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

Пр. 2:

var message = 'SO';

function foo(msg) {  //declares foo
    alert(msg);
}

(foo)(message);     // calls foo

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

Пр. 3.

var message = 'SO';

(function foo(msg) {
    alert(msg);
})(message);          // declares & calls foo

Наконец, нам не нужен этот дополнительный foo, потому что мы не используем имя для его вызова! Функции могут быть анонимными.

Пр. 4.

var message = 'SO';

(function (msg) {   // remove unnecessary reference to foo
    alert(msg);
})(message);

Чтобы ответить на ваш вопрос, вернитесь к примеру 2. Ваша первая строка объявляет некоторую безымянную функцию и группирует ее, но не вызывает ее. Вторая строка группирует строку. Оба ничего не делают. (Первый пример Винсента.)

(function (msg){alert(msg)});  
('SO');                       // nothing.

(foo); 
(msg); //Still nothing.

Но

(foo)
(msg); //works
93
ответ дан Benxamin 26 July 2015 в 15:23
поделиться

Это просто, как работает JavaScript. Вы можете объявить именованную функцию:

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

И вызвать ее:

foo("Hi!");

Или вы можете объявить анонимную функцию:

var foo = function (msg) {
    alert(msg);
}

И вызвать это :

foo("Hi!");

Или вы просто не можете связать функцию с именем:

(function(msg){
   alert(msg);
 })("Hi!");

Функции также могут возвращать функции:

function make_foo() {
    return function(msg){ alert(msg) };
}

(make_foo())("Hi!");

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

Это позволяет вам инкапсулировать информацию, если вы хотите:

function make_greeter(msg){
    return function() { alert(msg) };
}

var hello = make_greeter("Hello!");

hello();

Просто так работает почти каждый язык программирования, кроме Java.

19
ответ дан Peter Mortensen 26 July 2015 в 15:23
поделиться

Анонимная функция не является функцией с именем «». Это просто функция без имени.

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

Но, как и любое другое значение, вы иногда хотите использовать его без привязки к имени. Это самопризывная модель.

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

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

Таким образом, мы должны хранить их в переменной, чтобы иметь возможность использовать их, как любое другое значение:

var f = function(){ alert("plop"); }
var n = 2;

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

function f(){ alert("plop"); }
var n = 2;

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

(function(){ alert("plop"); })(); // will display "plop"
alert(2 + 3); // will display 5

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

Сказано, что это выглядит так, как будто вызывающая функция не имеет реального значения. Но вы должны иметь в виду, что разделитель области видимости JavaScript - это функция, а не блок ({}).

Таким образом, самопризывающаяся функция имеет то же значение, что и блок C ++, C # или Java. Это означает, что переменная, созданная внутри, не будет «вытекать» за пределы области видимости. Это очень полезно в JavaScript, чтобы не загрязнять глобальный охват.

23
ответ дан Peter Mortensen 26 July 2015 в 15:23
поделиться

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

alert(
    {foo: "I am foo", bar: "I am bar"}.foo
); // alerts "I am foo"

Относительно функций. Поскольку они являются объектами, которые наследуются от Function.prototype, мы можем делать такие вещи, как:

Function.prototype.foo = function () {
    return function () {
        alert("foo");
    };
};

var bar = (function () {}).foo();

bar(); // alerts foo

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

var x = function () {} (); // this function is executed but does nothing

function () {} (); // syntax error

Еще одна вещь, которую вы можете сделать с функциями, как только вы их объявите, - это вызвать над ними оператор new и получить объект. Следующее эквивалентно:

var obj = new function () {
    this.foo = "bar";
};

var obj = {
    foo : "bar"
};
3
ответ дан Ionuț G. Stan 26 July 2015 в 15:23
поделиться

Код, который вы показываете,

(function (msg){alert(msg)});
('SO');

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

var f = (function (msg){alert(msg)});
f('SO');

Обратите внимание, что, сохраняя анонимную функцию (лямбда-функцию) в переменной, вы фактически даете ей имя. Следовательно, вы также можете определить регулярную функцию:

function f(msg) {alert(msg)};
f('SO');
8
ответ дан Stephan202 26 July 2015 в 15:23
поделиться

примеры без скобок:

void function (msg) { alert(msg); }
('SO');

(это единственное реальное использование void, afaik)

или

var a = function (msg) { alert(msg); }
('SO');

или

!function (msg) { alert(msg); }
('SO');

тоже работают. void вызывает выражение для оценки, а также присваивания и взрыва. последний работает с ~, +, -, delete, typeof, с некоторыми унарными операторами (void также один). не работают из couse ++, -- из-за требования переменной.

разрыв строки не требуется.

3
ответ дан Nina Scholz 26 July 2015 в 15:23
поделиться

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

(function () {
    return ( 10 + 20 );
})();

Питер Мишо обсуждает разницу в Важная пара скобок .

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

См .:

  1. Закрытие (информатика)
  2. JavaScript Namespacing
  3. Важная пара скобок Javascript
1
ответ дан Ashwin Parmar 26 July 2015 в 15:23
поделиться

Подводя итог предыдущим комментариям:

function() {
  alert("hello");
}();

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

(function() {
  alert("hello");
})();

Это функция, вызывающая себя, то есть она создается анонимно и выполняется немедленно, потому что вызов происходит в той же строке, где он объявлен. Эта функция, вызывающая себя, обозначена знакомым синтаксисом для вызова функции без аргументов, а также добавлены круглые скобки вокруг имени функции: (myFunction)();.

Существует хороший SO SO-обсуждение синтаксиса функции JavaScript .

7
ответ дан Community 26 July 2015 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: