ListView также должен автоматически отображать вертикальную полосу прокрутки, если у вас есть достаточно элементов в коллекции (т. е. больше, чем может отображаться в ListView в настоящее время).
Удалите точку с запятой после определения функции.
(function (msg){alert(msg)})
('SO');
Выше должно работать.
Страница демонстрации: https://jsfiddle.net/e7ooeq6m/
Я обсуждал этот тип паттерна в этом посте:
РЕДАКТИРОВАТЬ:
Если вы посмотрите спецификацию сценария ECMA , есть 3 способа определения функции. (Стр. 98, раздел 13 «Определение функций»)
var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30
function sum(a, b)
{
return a + b;
}
alert(sum(10, 10)); //Alerts 20;
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.
Сравните это с
function test1() { alert(typeof test1) };
alert(typeof test1); //alerts 'function'
test1(); //alerts 'function'
Вооружившись этими знаниями, давайте попробуем проанализируйте ваш код.
Когда у вас есть подобный код,
function(msg) { alert(msg); }
Вы создали выражение функции. И вы можете выполнить это выражение функции, заключив его в круглые скобки.
(function(msg) { alert(msg); })('SO'); //alerts SO.
Анонимные функции - это функции, которые динамически объявляются во время выполнения. Их называют анонимными функциями, потому что им не дают имя так же, как обычным функциям.
Анонимные функции объявляются с использованием оператора функции вместо объявления функции. Вы можете использовать оператор функции, чтобы создать новую функцию везде, где допустимо поместить выражение. Например, вы можете объявить новую функцию в качестве параметра для вызова функции или назначить свойство другого объекта.
Вот типичный пример именованной функции:
function flyToTheMoon () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon (); Вот тот же пример, созданный как анонимная функция:
var flyToTheMoon = function () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon ();
Подробнее см. здесь:
http://helephant.com/2008/08/23/javascript-anonymous-functions/
Под анонимными функциями подразумевается одноразовая сделка, в которой вы определяете функцию на лету, чтобы она генерировала выходные данные из предоставленных вами входных данных. За исключением того, что вы не предоставили вход. Вместо этого вы написали что-то во второй строке («SO»); - независимое утверждение, которое не имеет ничего общего с функцией. Что ты ожидал? :)
Простая причина, по которой это не работает, не в том, что ;
указывает на конец анонимной функции. Это потому, что без ()
в конце вызова функции, это не вызов функции. То есть
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 также разрешают этот тип вызова функции, и я также считаю, что интерпретатор в любом случае добавляет скобки за кулисы, что возвращает нас к «вызову функции не является вызовом функции без скобок».
Другая точка зрения
Сначала вы можете объявить анонимную функцию:
var foo = function(msg){
alert(msg);
}
Затем вы вызываете ее:
foo ('Few');
Потому что foo = function (msg) {alert (msg);} , чтобы вы могли заменить foo на:
function(msg){
alert(msg);
} ('Few');
Но вы должны заключить всю анонимную функцию в пару фигурных скобок, чтобы избежать синтаксической ошибки объявления функции при разборе. Тогда мы имеем,
(function(msg){
alert(msg);
}) ('Few');
Таким образом, это легко понять для меня.
Когда вы сделали:
(function (msg){alert(msg)});
('SO');
Вы завершили функцию до ('SO')
из-за точки с запятой. Если вы просто напишите:
(function (msg){alert(msg)})
('SO');
Это будет работать.
Рабочий пример: http://jsfiddle.net/oliverni/dbVjg/
Есть еще одно свойство, которое имеет функция 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
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;
}());
(function (msg){alert(msg)})
('SO');
Это распространенный метод использования анонимной функции в качестве замыкания, который используют многие фреймворки JavaScript.
Эта функция вызывается автоматически при компиляции кода.
Если поместить ;
в первую строку, компилятор обрабатывает его как две разные строки. Таким образом, вы не можете получить те же результаты, что и выше.
Это также может быть записано как:
(function (msg){alert(msg)}('SO'));
Для более подробной информации, посмотрите в JavaScript / анонимные функции .
Это называется само-вызываемой функцией.
То, что вы делаете, когда вызываете (function(){})
, возвращает функциональный объект. Когда вы добавляете ()
к нему, он вызывается, и все в теле выполняется. ;
обозначает конец оператора, поэтому второй вызов завершается неудачей.
Мое понимание вопроса Аскера таково:
Как работает эта магия:
(function(){}) ('input') // Used in his example
Я могу ошибаться. Тем не менее, обычная практика, с которой знакомы люди:
(function(){}('input') )
Причина в том, что скобки JavaScript AKA ()
не могут содержать операторов, и когда парсер встречает ключевое слово function, он знает, анализировать его как выражение функции, а не как объявление функции.
Источник: запись в блоге Выражение функции, вызванной немедленно (IIFE)
Одна вещь, которую я нашел сбивающей с толку, это то, что "()" - это операторы группировки.
Вот ваша основная объявленная функция.
Пр. 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
Это просто, как работает 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.
Анонимная функция не является функцией с именем «». Это просто функция без имени.
Как и любое другое значение в 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, чтобы не загрязнять глобальный охват.
Этот ответ не имеет прямого отношения к вопросу, но вам может быть интересно узнать, что этот тип синтаксиса не является специфическим для функций. Например, мы всегда можем сделать что-то вроде этого:
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"
};
Код, который вы показываете,
(function (msg){alert(msg)});
('SO');
состоит из двух операторов. Первое - это выражение, которое возвращает функциональный объект (который затем будет собирать мусор, потому что он не сохраняется). Второе - это выражение, которое дает строку. Чтобы применить функцию к строке, вам нужно либо передать строку в качестве аргумента функции при ее создании (что вы также продемонстрировали выше), либо вам нужно будет фактически сохранить функцию в переменной, чтобы вы могли примените его позже, на досуге. Например:
var f = (function (msg){alert(msg)});
f('SO');
Обратите внимание, что, сохраняя анонимную функцию (лямбда-функцию) в переменной, вы фактически даете ей имя. Следовательно, вы также можете определить регулярную функцию:
function f(msg) {alert(msg)};
f('SO');
примеры без скобок:
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 ++
, --
из-за требования переменной.
разрыв строки не требуется.
Это самоисполняющаяся анонимная функция. Первый набор скобок содержит выражения, которые должны быть выполнены, а второй набор скобок выполняет эти выражения.
(function () {
return ( 10 + 20 );
})();
Питер Мишо обсуждает разницу в Важная пара скобок .
Это полезная конструкция при попытке скрыть переменные из родительского пространства имен. Весь код в функции содержится в закрытой области видимости функции, что означает, что к нему вообще нельзя получить доступ извне функции, что делает его действительно закрытым.
См .:
Подводя итог предыдущим комментариям:
function() {
alert("hello");
}();
, когда переменная не назначена, выдает синтаксическую ошибку. Код анализируется как оператор функции (или определение), что делает синтаксически некорректно закрывающие скобки. Добавление скобок вокруг части функции говорит интерпретатору (и программисту), что это выражение функции (или вызов), как в
(function() {
alert("hello");
})();
Это функция, вызывающая себя, то есть она создается анонимно и выполняется немедленно, потому что вызов происходит в той же строке, где он объявлен. Эта функция, вызывающая себя, обозначена знакомым синтаксисом для вызова функции без аргументов, а также добавлены круглые скобки вокруг имени функции: (myFunction)();
.
Существует хороший SO SO-обсуждение синтаксиса функции JavaScript .