在使用“new”运算符创建对象时,是否可以省略括号?
我见过对象是这样创建的:
const obj = new Foo;
但我认为在创建对象时括号不是可选的:
const obj = new Foo();
在 ECMAScript 标准中,前一种创建对象的方法是否有效且已定义?前者创建对象的方式与后者的创建方式之间有什么区别吗?一个是否优先于另一个?
我见过对象是这样创建的:
const obj = new Foo;
但我认为在创建对象时括号不是可选的:
const obj = new Foo();
在 ECMAScript 标准中,前一种创建对象的方法是否有效且已定义?前者创建对象的方式与后者的创建方式之间有什么区别吗?一个是否优先于另一个?
引用David Flanagan1:
作为一种特殊情况,仅对于运算符,JavaScript 通过允许在函数调用中没有参数时省略括号来简化语法。以下是使用运算符的一些示例:
new
new
o = new Object; // Optional parenthesis omitted here d = new Date(); ...
就个人而言,我总是使用括号,即使构造函数不带任何参数。
此外,如果您省略括号,JSLint可能会伤害您的感情。它报告了,并且该工具似乎没有一个选项可以容忍括号省略。Missing '()' invoking a constructor
1 David Flanagan: JavaScript the Definitive Guide: 4th Edition (第 75 页)
两者之间存在差异:
new Date().toString()
完美工作并返回当前日期new Date.toString()
throws “TypeError: Date.toString 不是构造函数"它发生是因为并且具有不同的优先级。根据MDN,我们感兴趣的JavaScript运算符优先级表的部分如下所示:new Date()
new Date
优先 | 运算符类型 | 关联性 | 运营商 |
---|---|---|---|
18 | 成员访问 计算成员访问 (带参数列表) new |
从左到右 从左到右 n/a |
… . … … [ … ] new … ( … )
|
17 | 函数调用 (不带参数列表) new |
从左到右 从右到左 |
… ( … ) new …
|
从此表中可以看出:
new Foo()
具有高于new Foo
new Foo()
与运算符具有相同的优先级.
new Foo
优先级比运算符低一级.
new Date().toString()
工作完美,因为它的评估为(new Date()).toString()
new Date.toString()
throw “TypeError: Date.toString 不是构造函数”,因为其优先级高于(并且高于“函数调用”),并且表达式的计算结果为.
new Date
(new (Date.toString))()
相同的逻辑可以应用于运算符。… [ … ]
new Foo
具有从右到左的关联性,并且对于“关联性”不适用。我认为在实践中,这没有任何区别。有关其他信息,请参阅此 SO 问题new Foo()
一个是否优先于另一个?
知道了所有这些,就可以假设这是首选。new Foo()