在javascript中,什么时候你想使用这个:

(function(){
    //Bunch of code...
})();

在这:

//Bunch of code...

当前回答

此方法用于闭包。有关闭包的更多信息,请阅读此链接。

其他回答

简单。所以看起来很正常,几乎令人欣慰:

var userName = "Sean";

console.log(name());

function name() {
  return userName;
}

但是,如果我在我的页面中包含一个非常方便的javascript库,它可以将高级字符转换为基本级别表示呢?

等待……什么?

我的意思是,如果有人输入一个带有某种口音的字符,但我只想在我的程序中输入“英语”字符a - z ?嗯…西班牙语的“ñ”和法语的“é”可以翻译成基本字符“n”和“e”。

所以有人写了一个全面的字符转换器,我可以包括在我的网站…我把它包括在内。

有一个问题:它有一个名为“name”的函数,与我的函数相同。

这就是所谓的碰撞。我们在同一个作用域中声明了两个同名的函数。我们要避免这种情况。

因此,我们需要以某种方式确定代码的范围。

在javascript中作用域代码的唯一方法是将其包装在函数中:

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter library's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

那也许能解决我们的问题。现在所有内容都是封闭的,只能从开括号和闭括号内访问。

我们有一个函数中的一个函数。看起来很奇怪,但完全合法。

只有一个问题。我们的代码不能工作。 我们的userName变量从来没有回显到控制台!

我们可以通过在现有代码块之后添加对函数的调用来解决这个问题…

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

main();

或之前!

main();

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

第二个问题是:“main”这个名字还没有被使用的可能性有多大?...非常非常苗条。

我们需要更多的范围。以及自动执行main()函数的方法。

现在我们来讨论自动执行函数(或自动执行、自动运行等等)。

((){})();

语法非常笨拙。然而,它是有效的。

当你用圆括号包装一个函数定义,并包含一个形参列表(另一个集合或圆括号!),它就像一个函数调用。

所以让我们再看看我们的代码,使用一些自动执行的语法:

(function main() {
  var userName = "Sean";
                
    console.log(name());
                
    function name() {
      return userName;
    }
  }
)();

所以,在你阅读的大多数教程中,你现在都会被“匿名自动执行”或类似的术语轰炸。

经过多年的专业开发,我强烈建议您为调试目的而编写的每个函数都命名。

当出现错误时(它会出错),您将在浏览器中检查回溯。当堆栈跟踪中的条目有名称时,总是更容易缩小您的代码问题!

我不敢相信没有一个答案提到隐含的全局变量。

(function(){})()构造不能防止隐含的全局变量,这对我来说是更大的问题,参见http://yuiblog.com/blog/2006/06/01/global-domination/

基本上,函数块确保你定义的所有依赖的“全局变量”都限制在你的程序中,它不保护你不定义隐式全局变量。JSHint或类似的文件可以提供关于如何防御这种行为的建议。

更简洁的var App ={}语法提供了类似级别的保护,并且可以在“公共”页面上包装在函数块中。(请参阅Ember.js或SproutCore了解使用此结构的库的真实示例)

至于私有属性,除非您正在创建一个公共框架或库,否则它们有点被高估了,但如果您需要实现它们,Douglas Crockford有一些很好的想法。

一个区别是,你在函数中声明的变量是局部的,所以当你退出函数时,它们就消失了,并且它们不会与其他或相同代码中的其他变量冲突。

简单的回答是:防止全球(或更高)范围的污染。

IIFE(立即调用函数表达式)是将脚本编写为插件、附加组件、用户脚本或任何期望与其他人的脚本一起工作的脚本的最佳实践。这可以确保您定义的任何变量都不会对其他脚本产生不良影响。

这是另一种写IIFE表达式的方法。我个人更喜欢以下方法:

void function() {
  console.log('boo!');
  // expected output: "boo!"
}();

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void

从上面的例子可以很清楚地看出,IIFE也会影响效率和性能,因为原本预计只运行一次的函数实际上只执行了一次,然后就永远被丢弃了。这意味着函数或方法声明不会保留在内存中。

你可以使用这个函数返回值:

var Test = (function (){ const alternative = function(){ return 'Error Get Function '}, methods = { GetName: alternative, GetAge:alternative } // If the condition is not met, the default text will be returned // replace to 55 < 44 if( 55 > 44){ // Function one methods.GetName = function (name) { return name; }; // Function Two methods.GetAge = function (age) { return age; }; } return methods; }()); // Call console.log( Test.GetName("Yehia") ); console.log( Test.GetAge(66) );