Javascript 对象/函数/类声明周围的括号是什么意思?

Javascript 对象/函数/类声明周围的括号是什么意思?,javascript,syntax,Javascript,Syntax,我对JavaScript和Java都是新手。在YUI库示例中,您可以找到此构造的许多用途: (function() { var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, layout = null, ... })(); 我认为最后两个括号是在声明之后执行函数 。。。但是关于函数声明的前一组括号呢 我认为这是一个范围问题;这是为了将内部变量隐藏到外部函数和可能的全局对象。它是?更一般地说,这些括号的机制

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

(function() {
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event,
    layout = null,
        ...
})();
我认为最后两个括号是在声明之后执行函数

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


我认为这是一个范围问题;这是为了将内部变量隐藏到外部函数和可能的全局对象。它是?更一般地说,这些括号的机制是什么?

如果您愿意,第一个括号用于表示操作顺序。围绕函数定义的一组括号的“结果”是函数本身,实际上,第二组括号执行该函数


至于它为什么有用,我还不是一个足够的JavaScript向导,我不知道P

这是一个自动执行的匿名函数。第一组括号包含要执行的表达式,第二组括号执行这些表达式

当试图从父命名空间隐藏变量时,它是一个有用的构造。函数中的所有代码都包含在函数的私有范围内,这意味着它根本不能从函数外部访问,从而使其真正私有

见:

安迪·休谟差不多就是答案,我只想补充一些细节

使用此构造,您将创建一个具有自己的计算环境或闭包的匿名函数,然后立即对其进行计算。这样做的好处是,您可以访问在匿名函数之前声明的变量,并且可以在该函数中使用局部变量,而不会意外地覆盖现有变量

var关键字的使用非常重要,因为在JavaScript中,默认情况下每个变量都是全局变量,但是使用关键字可以创建一个新的、词汇范围的变量,也就是说,它可以通过两个大括号之间的代码看到。在您的示例中,基本上是为YUI库中的对象创建短别名,但它有更强大的用途

我不想给大家留下一个代码示例,所以我将在这里放一个简单的示例来说明闭包:

var add_gen = function(n) {
  return function(x) {
    return n + x;
  };
};
var add2 = add_gen(2);
add2(3); // result is 5
这是怎么回事?在函数add_gen中,您正在创建另一个函数,该函数只需将数字n添加到其参数中。诀窍在于,在函数参数列表中定义的变量充当词汇范围内的变量,就像用var定义的变量一样

返回的函数是在add\u gen函数的大括号之间定义的,因此即使在add\u gen函数完成执行后,它也可以访问n的值,这就是为什么在执行示例的最后一行时会得到5

借助于词汇范围内的函数参数,您可以解决在匿名函数中使用循环变量所产生的“问题”。举一个简单的例子:

for(var i=0; i<5; i++) {
  setTimeout(function(){alert(i)}, 10);
}
(变量i=0;i)的

…但是上一轮围绕所有函数声明的parentese呢

具体来说,它使JavaScript将“function(){…}”构造解释为一个内联匿名函数表达式。如果省略括号:

function() {
    alert('hello');
}();
您将得到一个语法错误,因为JS解析器将看到'function'关键字,并假设您正在启动以下形式的函数语句:

function doSomething() {
}
…如果没有函数名,就不能有函数语句


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

请参见。如果使用函数,则不需要第一组括号但是一个无名函数需要这个构造,括号让程序员意识到他们在浏览代码时看到了一个自调用函数(参见一位博客作者的)。关于这个主题的一些注意事项:

  • 括号:

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

    [optional name]([optional parameters]){...code...}
    
    因此,在像function(){}()这样的表达式中,最后一个括号没有意义

    现在想想

    name=function(){} ; name() !?
    
是的,第一对括号强制匿名函数转换为变量(存储表达式),第二对括号启动求值/执行,因此函数(){})()有意义

  • 实用程序:

  • 用于在加载时执行一些代码,并将使用的变量与页面的其余部分隔离,尤其是在可能出现名称冲突时

  • 将eval(“字符串”)替换为

    (新函数(“字符串”))()

  • 为“=?:”运算符换行长代码,如:

    结果=exp_to_test?(函数(){…长代码…})(:(函数(){…})()


请继续安迪·休谟和其他人说过的话:

围绕匿名函数的“()”是ECMA规范第11.1.6节中定义的“分组运算符”:

从文档中逐字记录:

11.1.6分组运算符

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

  • 返回计算表达式的结果。这可能是引用类型

  • 在此上下文中,函数被视为表达式。

    括号仅在此上下文中是必需的,因为JavaScript中的
    function
    可以是语句也可以是表达式,具体取决于上下文。括号强制它成为表达式。以下内容也有效:
    var x=function(){return 1}()
    即使没有括号。只有一个函数表达式和所述表达式的应用程序(…)
    。在这种情况下,我建议在t前面加一个
    name=function(){} ; name() !?