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

TK1*_*123 14 javascript

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

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

foo();
Run Code Online (Sandbox Code Playgroud)

我宁愿这样做:

(function foo() {
   alert('hello');
})();
Run Code Online (Sandbox Code Playgroud)

问题是,这只会在页面加载时执行,但如果我尝试使用foo()它后续调用它将无法正常工作.

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

小智 34

如果你的函数不依赖于返回值,你可以这样做......

var foo = (function bar() {
   alert('hello');
   return bar;
})();   // hello

foo();  // hello
Run Code Online (Sandbox Code Playgroud)

这使用bar命名函数表达式中的本地引用将函数返回到外部foo变量.


或者即使它确实如此,你也可以使返回值有条件......

var foo = (function bar() {
   alert('hello');
   return foo ? "some other value" : bar;
})();   // hello

alert( foo() );  // hello --- some other value
Run Code Online (Sandbox Code Playgroud)

或者只是手动分配给变量而不是返回...

var foo; 
(function bar() {
   alert('hello');
   foo = bar;
})();   // hello

foo();  // hello
Run Code Online (Sandbox Code Playgroud)

正如@RobG所指出的,IE的某些版本会将标识符泄漏到封闭变量范围中.该标识符将引用您创建的函数的副本.要使您的NFE IE安全(r),您可以使该引用无效.

bar = null;
Run Code Online (Sandbox Code Playgroud)

请注意,标识符仍会影响范围链上具有相同名称的标识符.Nullifying对此无效,并且无法删除局部变量,因此请明智地选择NFE名称.


nnn*_*nnn 5

如果foo()要成为全局函数,即 的属性window,您可以这样做:

(window.foo = function() {
   alert('hello');
})();

// at some later time
foo();
Run Code Online (Sandbox Code Playgroud)

第一组括号中的表达式执行对 create 的赋值foo,但也计算为函数,以便您可以在()最后立即调用它。

即使函数应该返回一个值,这种模式也有效。