关于javascript:围绕对象/函数/类声明的括号是什么意思?

What do parentheses surrounding an object/function/class declaration mean?

本问题已经有最佳答案,请猛点这里访问。

我对javascript和yui都是新手。在yui库示例中,您可以找到此构造的许多用途:

1
2
3
4
5
6
(function() {
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event,
    layout = null,
        ...
})();

我认为最后两个括号是在声明之后执行函数。

…但是关于函数声明的前一组括号呢?

我认为这是一个范围问题;那就是将变量隐藏在外部函数和可能的全局对象的内部。它是?一般来说,这些圆括号的力学原理是什么?


这是一个自我执行的匿名函数。第一组括号中的表达式的执行,第二个括号组executes那些表达式。

它是有用的当试图隐藏变量构建从父命名空间。所有的代码在函数是包含在私人范围的功能,它不能访问的意思是在所有的功能以外,制作真正的私人信息。

湖:

http:///wiki/闭合产生的_ 28computer _科学29 % %

http:/ / / / peter.michaux.ca JavaScript namespacing文章


安迪漂亮多了休谟的答案,我只是想添加一些更多的细节。

你是创造这一匿名函数的构建和评价自己的环境或闭包,然后你即刻评估它。关于这个漂亮的事情是,你可以访问变量的感知在匿名函数的本地变量,你可以使用这个功能没有在您的overwriting现有的变量。

使用var关键字是非常重要的,因为在JavaScript的变量是一个全球的默认,但在你创建一个新lexically关键字,一个变量,这是可见的,它是由两个括号之间的代码。在你的例子里,你是个不短的别名对象在YUI库,但它有更强大的使用。

我不想离开你,没有代码的例子在这里,所以我会把简单的例子,说明A到A的闭包。

1
2
3
4
5
6
7
var add_gen = function(n) {
  return function(x) {
    return n + x;
  };
};
var add2 = add_gen(2);
add2(3); // result is 5

是什么事吗?在_基因的功能添加功能创造另一个你希望添加到它的简单的数N的论点。的伎俩是在变量定义在函数的参数列表lexically作为一个变量,一个变量的定义的类。

返回的功能是定义的附加括号之间的_基因功能很有价值,甚至进入N基因功能添加_安切洛蒂完成后执行,这是为什么你想得到5当执行载重线的例子。

一个函数的参数是一个lexically帮助工作,你可以在"问题",而引起的循环变量和使用匿名函数。以简单的例子:

1
2
3
for(var i=0; i<5; i++) {
  setTimeout(function(){alert(i)}, 10);
}

"预期"的结果可能是从零到四个号码,但你得到的实例而不是四被。发生这种情况因为匿名函数在setTimeout和for循环使用的是非常变量在同一时间的函数,这样我会得到评价,5。

你可以得到预期的结果naively使用的技术在您的问题,事实上,这是一个lexically函数参数。(我用这个方法在其他的答案)

1
2
3
4
5
6
for(var i=0; i<5; i++) {
  setTimeout(
     (function(j) {
       return function(){alert(j)};
     })(i), 10);
}

一个即刻评价外部函数你创建一个完全独立的变量命名J在每个迭代,和当前的价值,我会在本copied在变,所以你想要得到的结果是什么naively预计从第一次。

我建议你尝试了解的一个很好的教程在http://ejohn.org /程序/了解/明白我在哪里关闭更好,这是非常,非常多。


...but what about the previous round parenteses surrounding all the function declaration?

具体来说,它使javascript将"function()…"构造解释为内联匿名函数表达式。如果省略括号:

1
2
3
function() {
    alert('hello');
}();

您将得到一个语法错误,因为JS解析器将看到"function"关键字,并假定您正在启动一个形式为的函数语句:

1
2
function doSomething() {
}

…如果没有函数名,就不能有函数语句。

函数表达式和函数语句是两种不同的构造,它们的处理方式非常不同。不幸的是,语法几乎是相同的,所以它不仅让程序员感到困惑,甚至连解析器也很难分辨出您的意思!


Juts将跟进安迪·休姆和其他人所说的话:

围绕匿名函数的"()"是ECMA规范第11.1.6节中定义的"分组运算符":http://www.ecma-international.org/publications/files/ecma-st/ecma-262.pdf。

从文件中逐字记录:

11.1.6分组运算符

production primaryExpression:(表达式)的计算如下:

  • 返回计算表达式的结果。这可能是类型引用。
  • 在此上下文中,函数被视为表达式。


    关于这个问题的几个考虑:

    • 括号:

      浏览器(引擎/解析器)将关键字函数与

      1
      [optional name]([optional parameters]){...code...}

      所以在像函数()()这样的表达式中,最后一个括号没有意义。

      现在想想

      1
      name=function(){} ; name() !?

    是的,第一对括号强制匿名函数转换为变量(存储表达式),第二对括号启动计算/执行,因此(function())()是有意义的。

    • 效用:?

    • 在加载时执行一些代码,并将使用的变量与页面的其余部分隔离开来,特别是在可能发生名称冲突时;

    • 将eval("字符串")替换为

      (新函数("string"))()

    • "="的长代码换行:"操作员:

      结果=实验到实验?(函数()…long_code…)():(function()…)();


    第一个括号是,如果你想订单业务。"result"一套括号周围的函数定义函数本身是事实,其中,第二组executes括号。

    为什么它是有用的作为是不够的,我有一个JavaScript的任何向导。:P


    看看这个问题。如果使用函数名,则不需要第一组括号,但无名称函数需要此构造,并且括号可供编码人员了解,他们在浏览代码时查看了自调用函数(请参阅一位博客作者的最佳实践建议)。