为什么要在函数定义 - 调用对中编写全局代码?

时间:2010-05-24 15:14:33

标签: javascript

我看到包含jQuery和jslint的JavaScript代码使用下面的符号的示例:

(function(){
  // do something
})();

而不是:

// do something

我首先认为这仅适用于本地范围,即为代码块创建局部变量而不会污染全局命名空间。但我见过没有任何局部变量的实例。

我在这里缺少什么?

5 个答案:

答案 0 :(得分:8)

它也是关于函数的范围 - 代码块中声明的所有内容都只限于该匿名函数。事情通常由框架公开

(function($) {

  var localVarOnly = "local";

  $.fn.myCoolFunction = function() { // in the case of jquery, make this publicly available
    otherCoolFunction(); //alerts hi
    alert(localVarOnly); // alerts local
  };

  function otherCoolFunction() { // scoped to this anonymous function only
    alert('hi');
  };

})(jQuery);

otherCoolFunction(); // undefined
alert(localVarOnly); // undefined

答案 1 :(得分:4)

正如其他人所说,这与创建本地范围完全相关。另一个好处是你可以使用它(为了更好的词)“重命名”变量。例如,几个javascript框架如何使用$作为其主库函数的简写。如果你在你的例子中创建一个闭包,那么<{1}} 之外的什么并不重要,你可以将它作为一个参数使用,里面它可以是你想要的任何东西:

$

使用相同的技术来创建未定义的变量的另一个小技巧是使用额外的几毫秒的脚本。大多数人认为// out here $ might be Prototype, something else, or even undefined (function($) { // in here, $ is jQuery })(jQuery); 是javascript中的一个特殊关键字,但它实际上只被视为一个普通变量,你希望没有人会定义它。检查未定义变量的标准做法:

undefined

...实际上相当浪费,因为它检查整个范围链中是否有一个名为“undefined”的变量。要快捷方式,您可以使用此方法:

if (x == undefined)

现在(function($, undefined) { // code here })(jQuery); // note that there's just one parameter passed 实际上在一个范围内(具有未定义的值),检查范围链可以在此时停止。微优化,是的,但知道它并没有什么坏处。

答案 2 :(得分:3)

这种(Crockford)模式的主要目的(还有其他 - 在某些情况下也更具性能)是通过命名函数/标识符来避免全局范围的污染。通过在这个匿名闭包中执行操作,您可以像在全局范围内一样编写代码,除了在内部声明的所有内容都保持在本地,因此无法从外部访问/引用。没有使用局部变量/函数或“导出”(从一个外部作用域分配给命名标识符)的用例可能存在,但不一定必须嵌套在匿名函数中。

答案 3 :(得分:3)

该语法是创建本地范围,正如其他人所评论的那样,但也是为了使函数自动执行。请注意,只需创建本地范围也可以这样完成:

var foo = function(){
   // local code
};
foo();

但是,如果这就是你所做的一切,并且foo除了一次调用之外没有其他任何实用程序,那么匿名的,自动执行的语法只会为你节省额外的var声明:

(function(){
   // local code
})();

在使用OOP模式的框架中,这也是用于创建单例的语法,因为该函数只能运行一次,并且永远不能被外部代码再次调用。

答案 4 :(得分:1)

这是为了创建一个包含声明的所有变量的范围。这是为了避免污染全局范围并避免覆盖已存在的变量。

以此为例

(function() {
    var foo = "bar";
    var undefined = true;
    var bar = true;

    alert(foo); //bar
    if (bar == undefined) {
        alert("bar is undefined.. not!"); //will show even though we know that bar is not 'undefined'
    }

})();

var bar = true;
alert(foo) //undefined
if (bar == undefined) {
    alert("bar is undefined"); // will not be called
}

当谈到模式时,(function(){/*....*/})();目前正在comp.lang.javascript讨论如何称呼这个结构,以及谁应该得到它的信誉:)