如何在JavaScript中调用自执行函数?

时间:2012-06-05 00:50:01

标签: javascript

当我有一些代码时,我需要多次执行,我将它包装在一个函数中,所以我不必重复自己。有时需要在页面加载时最初执行此代码。现在我这样做:

function foo() {
   alert('hello');
}

foo();

我宁愿这样做:

(function foo() {
   alert('hello');
})();

问题是,这只会在页面加载时执行,但如果我尝试使用foo()后续调用它,则无效。

我猜这是一个范围问题,但有没有办法让自动执行函数在以后调用时工作?

4 个答案:

答案 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);
}