当我有一些代码时,我需要多次执行,我将它包装在一个函数中,所以我不必重复自己。有时需要在页面加载时最初执行此代码。现在我这样做:
function foo() {
alert('hello');
}
foo();
我宁愿这样做:
(function foo() {
alert('hello');
})();
问题是,这只会在页面加载时执行,但如果我尝试使用foo()
后续调用它,则无效。
我猜这是一个范围问题,但有没有办法让自动执行函数在以后调用时工作?
答案 0 :(得分:32)
如果你的功能不依赖于返回值,你可以这样做......
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安全(r),您可以使该引用无效。
bar = null;
请注意,标识符仍然会在范围链上覆盖与名称相同的标识符。 Nullifying对此无效,并且无法删除局部变量,因此请明智地选择NFE名称。
答案 1 :(得分:4)
要从外部调用,必须从外部看到该功能。理想情况下,你会让自执行函数在一些传入的上下文中引入它(在本例中,this
引用全局上下文):
(function(context) {
var foo = function() {
alert('hello');
};
foo();
context.foo = foo;
})(this);
...
foo();
可以找到更有趣的模式here。
答案 2 :(得分:4)
如果foo()
旨在成为全局函数,即window
的属性,则可以执行此操作:
(window.foo = function() {
alert('hello');
})();
// at some later time
foo();
第一组括号中的表达式执行创建foo
的赋值,但也计算为函数,因此您可以在最后使用()
立即调用它。
即使该函数应该返回一个值,这种模式仍然有效。
答案 3 :(得分:0)
第二个函数foo
是函数定义表达式。
在函数定义表达式中,您只能根据" Javascript权威指南":
在函数本身中调用具有名称的函数。对于函数定义表达式,名称是可选的:如果存在,则名称仅引用函数本身中的函数对象。
它可以用在递归函数定义表达式中。
例如:
var f = function factorial(n) {
if (n == 0 || n == 1)
return 1;
else
return n * factorial(n-1);
}