当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《围绕对象/函数/类声明的括号是什么意思?》经验,为你挑选了5个好方法。

我是JavaScript和YUI的新手.在YUI库示例中,您可以找到此构造的许多用法:

(function() {
    var Dom = YAHOO.util.Dom,
    Event = YAHOO.util.Event,
    layout = null,
        ...
})();

我认为最后几个括号是在声明之后执行该函数.

...但是围绕函数声明的前一组括号怎么样?

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



1> Andy Hume..:

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

尝试隐藏父命名空间中的变量时,它是一个有用的构造.函数中的所有代码都包含在函数的私有范围内,这意味着它无法从函数外部访问,从而使其真正成为私有.

看到:

http://en.wikipedia.org/wiki/Closure_%28computer_science%29

http://peter.michaux.ca/articles/javascript-namespacing


括号仅在此上下文中是必需的,因为JavaScript中的`function`可以是语句或表达式,具体取决于上下文.括号迫使它成为表达式.以下也是有效的:`var x = function(){return 1}()`即使没有周围的括号.只是一个函数表达式和所述表达式的应用程序`(...)`.在我这样的情况下,我建议在左括号之前放一个`;`:我写一个半冒号的自由代码和以`(`开头的行可以解析为从前一行继续的表达式.

2> bandi..:

Andy Hume几乎给出了答案,我只想补充一些细节.

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

使用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_gen函数的大括号之间定义,因此即使在add_gen函数执行完毕后它也可以访问n的值,这就是为什么在执行示例的最后一行时会得到5.

借助于词法范围的函数参数,您可以解决在匿名函数中使用循环变量引起的"问题".举一个简单的例子:

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

"预期"结果可能是从零到四的数字,但是你会得到四个五的实例.发生这种情况是因为setTimeout和for循环中的匿名函数使用了非常相同的 i变量,因此在评估函数时,将为5.

您可以通过在您的问题中使用该技术以及函数参数是词法范围的事实来获得天真预期的结果.(我在另一个答案中使用过这种方法)

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

通过立即评估外部函数,您将在每次迭代中创建一个名为j的完全独立的变量,并且i的当前值将被复制到此变量中,因此您将获得第一次尝试时天真期望的结果.

我建议你尝试理解http://ejohn.org/apps/learn/上的优秀教程,以便更好地理解闭包,这是我非常了解的地方.


真棒的答案!谢谢!

3> bobince..:

......但是围绕所有功能声明的前一轮问题呢?

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

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

你会得到一个语法错误,因为JS解析器会看到'function'关键字并假设你正在启动一个表单的函数声明:

function doSomething() {
}

...并且没有函数名称就没有函数语句.

函数表达式和函数语句是两种不同的结构,它们以非常不同的方式处理.不幸的是,语法几乎完全相同,所以它不仅仅让程序员感到困惑,即使解析器很难说出你的意思!



4> 小智..:

Juts跟进Andy Hume和其他人所说的话:

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

从文档中逐字逐句:

11.1.6分组运算符

生产PrimaryExpression:(Expression)的计算方法如下:

    返回评估Expression的结果.这可能是参考类型.

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


:(
)的计算方法如下:
的结果.这可能是参考类型.

5> bortunac..:

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

括号:

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

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

所以在像function(){}()这样的表达式中,最后一个括号没有意义.

现在想想

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

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

实用程序:?

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

    将eval("string")替换为

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

    包含" = ?: "运算符的长代码,如:

    result = exp_to_test?(function(){... long_code ...})():( function(){...})();

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有