Can we omit parentheses when creating an object using the “new” operator?
我见过这样创建的对象:
1 | const obj = new Foo; |
但我认为在创建对象时括号不是可选的:
1 | const obj = new Foo(); |
前一种创建对象的方法是否有效并在ECMAScript标准中定义?前一种创建对象的方式和后一种创建对象的方式有什么区别吗?一个比另一个更受欢迎吗?
引用大卫·弗拉纳加1:
As a special case, for the
new operator only, JavaScript simplifies the grammar by allowing the parenthesis to be omitted if there are no arguments in the function call. Here are some examples using thenew operator:
1
2
3
4 o = new Object; // Optional parenthesis omitted here
d = new Date();
...
就我个人而言,我总是使用括号,即使构造函数不接受参数。
此外,如果省略括号,jslint可能会伤害您的感情。它报告了
1大卫·弗拉纳根:javascript最终指南:第4版(第75页)
两者之间存在差异:
new Date().toString() 工作正常,返回当前日期new Date.toString() 抛出"typeerror:date.toString不是构造函数"
这是因为
1 2 3 4 5 6 7 8 9 10 | ╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗ ║ Precedence ║ Operator type ║ Associativity ║ Operators ║ ╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣ ║ 18 ║ Member Access ║ left-to-right ║ … . … ║ ║ ║ Computed Member Access ║ left-to-right ║ … [ … ] ║ ║ ║ new (with argument list) ║ n/a ║ new … ( … ) ║ ╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣ ║ 17 ║ Function Call ║ left-to-right ║ … ( … ) ║ ║ ║ new (without argument list) ║ right-to-left ║ new … ║ ╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝ |
从下表可以看出:
同样的逻辑也适用于
Is one preferred over the other?
知道这些,我们可以假定,最好是
我认为当你使用"新"操作符时没有什么区别。注意养成这个习惯,因为这两行代码不一样:
1 2 | var someVar = myFunc; // this assigns the function myFunc to someVar var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar |
如果没有要传递的参数,则括号是可选的。省略它们只是语法上的甜头。
https://people.mozilla.org/~jorendorff/es6 draft.html sec新操作员运行时语义评估
这是ES6规范的一部分,它定义了这两个变体的操作方式。无括号变量传递一个空参数列表。
有趣的是,这两种形式有不同的语法意义。当您尝试访问结果的成员时,会出现这种情况。
1 2 | new Array.length // fails because Array.length is the number 1, not a constructor new Array().length // 0 |
两者没有区别。