Как вызвать функцию самоисполнения в JavaScript?
Когда у меня есть код, который мне нужно выполнить несколько раз, я завершаю его функцией, поэтому мне не нужно повторять. Иногда, кроме того, необходимо выполнить этот код изначально при загрузке страницы. Сейчас я делаю так:
function foo() {
alert('hello');
}
foo();
Я бы предпочел сделать это следующим образом:
(function foo() {
alert('hello');
})();
Проблема в том, что это будет выполняться только при загрузке страницы, но если я попытаюсь вызвать ее в последующие моменты времени с помощью foo()
, это не сработает.
Я предполагаю, что это проблема с областью, но есть ли способ заставить себя выполнять функции, чтобы работать после вызова позже?
Ответы
Ответ 1
Если ваша функция не полагается на возвращаемое значение, вы можете сделать это...
var foo = (function bar() {
alert('hello');
return bar;
})(); // hello
foo(); // hello
Здесь используется локальная ссылка bar
в названном выражении функции для возврата функции к внешней переменной foo
.
Или даже если это произойдет, вы можете сделать возвращаемое значение условным...
var foo = (function bar() {
alert('hello');
return foo ? "some other value" : bar;
})(); // hello
alert( foo() ); // hello --- some other value
или просто назначьте переменную вместо возврата...
var foo;
(function bar() {
alert('hello');
foo = bar;
})(); // hello
foo(); // hello
Как отмечено @RobG, некоторые версии IE будут терять идентификатор в охватывающей области переменных. Этот идентификатор будет ссылаться на дубликат созданной вами функции. Чтобы сделать ваш NFE IE-safe (r), вы можете аннулировать эту ссылку.
bar = null;
Просто имейте в виду, что идентификатор по-прежнему будет затенять идентификатор с тем же именем в цепочке областей видимости. Обнуление не поможет, и локальные переменные не могут быть удалены, поэтому разумно выбирайте имя NFE.
Ответ 2
Чтобы вызываться извне, функция должна быть видна снаружи. В идеале у вас будет функция самоисполнения, которая вводит ее в некотором переданном контексте (в данном случае this
, который ссылается на глобальный контекст):
(function(context) {
var foo = function() {
alert('hello');
};
foo();
context.foo = foo;
})(this);
...
foo();
Более интересные шаблоны можно найти здесь.
Ответ 3
Если foo()
предназначена для глобальной функции, то есть для свойства window
, вы можете сделать это:
(window.foo = function() {
alert('hello');
})();
// at some later time
foo();
Выражение в первом наборе скобок делает назначение для создания foo
, но также оценивается как функция, поэтому вы можете немедленно вызвать его с помощью ()
в конце.
Этот шаблон работает, даже если функция должна возвращать значение.
Ответ 4
Вторая функция foo
- выражение определения функции.
В выражении определения функции вы можете только вызвать функцию с именем внутри самой функции в соответствии с "Javascript: окончательное руководство":
Для выражений определения функции имя необязательно: если оно присутствует, имя относится к объекту функции только внутри тела самой функции.
Он может использоваться в выражении определения функции рекурсии.
Например:
var f = function factorial(n) {
if (n == 0 || n == 1)
return 1;
else
return n * factorial(n-1);
}