【问题标题】:What is the difference between these 2 JavaScript declarations?这两个 JavaScript 声明有什么区别?
【发布时间】:2012-04-01 19:21:28
【问题描述】:

其中一个“()”在里面,另一个在外面。他们来了:

var a = (function() {
    return {
        bla: function() {
            console.log('a');
        }
    };
} () );

var b = (function() {
    return {
        bla: function() {
            console.log('b');
        }
    };
}) ();

a.bla();
b.bla();

【问题讨论】:

标签: javascript


【解决方案1】:

没有区别。

[不必要的]括号只是在不同的地方。由于其所在的位置,函数声明已经是一个表达式。如果声明在 statement context 中(讽刺的是,他们会将其转回 expression context),括号会有所不同,同时仍会产生等效代码,它不是。


类似场景中括号的常见用途是用于自调用函数。在这种情况下需要括号,因为

function x () { alert("hi!") } ()

被解析为

function x () { alert("hi!") }; ()

当它作为一个语句出现时——或“块的顶级元素”——它被解析为一个“FunctionDeclaration”。因此经常使用以下形式:

(function () { alert("hi!") })()

这是因为function ... 不再是一个语句,如上所述,而是一个表达式(解析为 "FunctionExpression"),并且表达式 可以 继续Automatic Semicolon Insertion 不会像前一种情况那样出现。还要注意函数名可以省略。

但是,因为在帖子中function ... 出现在=(在“AssignmentExpression” 中)的右侧,因此它已经在表达式上下文(被解析为“FunctionExpression”),因此不需要额外的括号。

所有这些都是相同的,但我更喜欢第二种形式(为了在 my 代码中保持一致性):

a = function () {} ()
b = (function () {}) ()
c = (function () {} ())

编码愉快。

【讨论】:

  • 您愿意解释一下什么是“语句上下文”吗?
  • @Kumar 语法规则见section 12 of the ECMAScript 5th edition。我为创建函数对象的两种不同的语法结构添加了“正确的”术语。请注意,ExpressionStatement不能{function 开头,这会强制将作为块的“顶级元素”出现的函数定义视为 FunctionDeclaration。
【解决方案2】:

没有真正的区别。两者的工作方式相同。如果要传递JSLint,则需要使用第一个模式,其中调用括号位于另一组括号内。如果不这样做,您将收到以下错误:

将调用移动到包含函数的括号中。

另请注意,第一组括号不是必需的。没有它们它也可以工作,但 JSLint 会再次失败:

将立即函数调用包装在括号中以帮助 读者理解该表达式是 函数,而不是函数本身。


几个相关问题:

JSLint error: "Move the invocation into the parens that contain the function"

Solution for JSLint errors

【讨论】:

  • 你有没有找到任何理由为什么这个选择是在 JSLint 中做出的?这似乎是任意的......
  • @Guffa - 我认为这是任意的。正是克罗克福德认为他喜欢的东西。就个人而言,我倾向于遵循这 2 个 JSLint 规则,但我很确定它绝对没有区别(至少在这种情况下)。
  • 我相信外括号是出于可读性的原因。他们清楚地表明,结束 () 不是一个错字,以便将来由其他不熟悉 JS 更复杂功能的开发人员进行任何编辑。恕我直言,同样适用于速记 if 的 x == 1 ? 'foo' : y == 2 ? 'foobar' : 'bar' 需要更长的阅读时间并且比 (x == 1 ? 'foo' : (y == 2 ? 'foobar' : 'bar')) 更容易出错。以后也更容易编辑...
  • 我不喜欢(或使用)JSLint,但 +1 指出了这个......怪癖。
【解决方案3】:

没有实际的区别,只是你如何让 Javascript 引擎将函数视为一个值的细微差别。

使用( function(){} () ); 会使函数成为一个值,因为语句不能以括号开头。使用( function(){} ) ();,您使用括号首先将函数评估为一个值,然后调用它。

【讨论】:

  • 在这两种情况下,function(){} 首先被评估为一个函数对象。括号会强制它成为一个表达式......但它已经是这样了。
  • @pst:是的,在这种情况下它已经是一个表达式,但是在这种情况下,括号的常见用法是使其成为一个表达式。这就是括号存在的原因,即使在赋值时不需要它们。
  • 还不错;为了保持一致性,我确实更喜欢 [inside] 括号形式。
【解决方案4】:

我觉得和这个的区别是一样的:

var myObj = {bla:'blabla'}; 
var a = (myObj);
var b = myObj;

...没有区别:)

【讨论】:

    【解决方案5】:

    结束括号的意思是:当一个函数被立即调用时,整个调用表达式应该用括号括起来,这样就很清楚产生的值是函数的结果,而不是函数本身。 (取自here

    因此,如果您使用 {}(),则​​该函数会立即执行,并将函数结果分配给变量。

    那么如果你使用({})(),如果()之间有一个函数,它就会被执行,并将值赋给变量。

    在我看来,如果它们包含相同的功能,它们就是相同的东西。

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 2017-08-13
      • 2016-05-08
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多