使用“new”运算符创build对象时,我们可以省略括号吗?

我已经看到了这样创build的对象:

const obj = new Foo; 

但我认为创build对象时,括号不是可选的:

 const obj = new Foo(); 

以前在ECMAScript标准中创build对象的方法是否有效和定义? 前者创造物体的方式和后来的方式有什么区别吗? 一个比另一个更受欢迎吗?

引用David Flanagan 1

作为一种特殊情况,对于仅限于new操作符的情况,如果在函数调用中没有参数,那么JavaScript通过允许省略括号来简化语法。 以下是使用new运算符的一些示例:

 o = new Object; // Optional parenthesis omitted here d = new Date(); ... 

就个人而言,我总是使用括号,即使构造函数不带参数。

另外,如果省略括号, JSLint可能会伤害你的感觉。 它报告Missing '()' invoking a constructor ,似乎没有这个工具可以容忍括号省略的选项。


1 David Flanagan: JavaScript权威指南:第4版 (第75页)

两者之间有差异:

  • new Date().toString()完美的作品,并返回当前的date
  • new Date.toString()抛出“ TypeError:Date.toString不是一个构造函数

这是因为new Date()new Date具有不同的优先级。 根据MDN对我们感兴趣的JavaScript运算符优先级表的部分如下:

 ╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗ ║ 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 … ║ ╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝ 

从这张表中可以看出:

  1. new Foo()具有更高的优先级,然后new Foo

    new Foo()具有new Foo()相同的优先级. 操作者

    new Foo优先级就低一级了. 操作者

    new Date().toString()完美工作,因为它的计算结果为(new Date()).toString()

    new Date.toString()抛出“ TypeError:Date.toString不是一个构造函数 ”,因为. 具有更高的优先级,然后new Date (和更高的“函数调用”)和expression式计算为(new (Date.toString))()

    同样的逻辑可以应用于… [ … ]操作员。

  2. new Foo具有从右到左的关联性,对于new Foo() “关联性”是不适用的。 我认为在实践中并没有什么区别。 有关更多信息,请参阅此 SO问题


一个比另一个更受欢迎吗?

知道所有可以假定new Foo()是首选。

当您使用“新”运算符时,我不认为有任何区别。 注意进入这个习惯,因为这两行代码是不一样的:

 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-new-operator-runtime-semantics-evaluation

这里是ES6规范的一部分,它定义了两个变体如何操作。 无括号变体传递一个空的参数列表。

有趣的是,这两种forms有不同的语法意义。 当您尝试访问结果的成员时出现。

 new Array.length // fails because Array.length is the number 1, not a constructor new Array().length // 0