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

新手上路,请多包涵

我见过以这种方式创建的对象:

 const obj = new Foo;

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

 const obj = new Foo();

前一种创建对象的方法是否有效并在 ECMAScript 标准中定义?前一种创建对象的方式与后一种方式有什么区别吗?一个比另一个更受欢迎吗?

原文由 Behrang 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 538
2 个回答

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

原文由 Daniel Vassallo 发布,翻译遵循 CC BY-SA 4.0 许可协议

两者有区别:

  • new Date().toString() 完美运行并返回当前日期
  • new Date.toString() 抛出“ TypeError: Date.toString is not a constructor

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

优先级操作员类型结合性运营商18会员权限

计算成员访问

new (带参数列表)左到右

左到右

不适用… . …

… [ … ]

new … ( … ) 17函数调用

new (无参数列表)左到右

右到左… ( … )

new …

从这个表可以看出:

  1. new Foo() 优先级高于 new Foo

new Foo(). 运算符具有相同的优先级

new Foo. 运算符低一级优先级

new Date().toString() 完美工作,因为它评估为 (new Date()).toString()

new Date.toString() 抛出“ TypeError: Date.toString is not a constructor ” 因为 . 的优先级高于 new Date 和“调用函数”(以及更高的表达式)评估为 (new (Date.toString))()

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

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

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

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

原文由 traxium 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题