使用“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 … ║ ╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝
从这张表中可以看出:
-
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))()
同样的逻辑可以应用于
… [ … ]
操作员。 -
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