在使用“new”运算符创建对象时,是否可以省略括号?

2022-08-30 00:23:22

我见过对象是这样创建的:

const obj = new Foo;

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

const obj = new Foo();

在 ECMAScript 标准中,前一种创建对象的方法是否有效且已定义?前者创建对象的方式与后者的创建方式之间有什么区别吗?一个是否优先于另一个?


答案 1

引用David Flanagan1

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

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 页)


答案 2

两者之间存在差异:

  • new Date().toString()完美工作并返回当前日期
  • new Date.toString()throws “TypeError: Date.toString 不是构造函数"

它发生是因为并且具有不同的优先级。根据MDN,我们感兴趣的JavaScript运算符优先级表的部分如下所示:new Date()new Date

优先 运算符类型 关联性 运营商
18 成员访问
计算成员访问
(带参数列表)new
从左到右
从左到右
n/a
… . …
… [ … ]
new … ( … )
17 函数调用
(不带参数列表)new
从左到右
从右到左
… ( … )
new …

从此表中可以看出:

  1. 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))()

    相同的逻辑可以应用于运算符。… [ … ]

  2. new Foo具有从右到左的关联性,并且对于“关联性”不适用。我认为在实践中,这没有任何区别。有关其他信息,请参阅 SO 问题new Foo()


一个是否优先于另一个?

知道了所有这些,就可以假设这是首选。new Foo()