我看到过这样创建的对象:
const obj = new Foo;
但是我认为创建对象时括号不是可选的:
const obj = new Foo();
创建对象的前一种方法在ECMAScript标准中是否有效并定义?前一种创建对象的方式与后一种创建方式有什么区别吗?是一个比另一个更好的选择吗?
new a.b()
与的不同之处new a().b()
在于,在前一种情况下,a.b
首先访问,而在后一种情况下,a
首先创建一个新。
我看到过这样创建的对象:
const obj = new Foo;
但是我认为创建对象时括号不是可选的:
const obj = new Foo();
创建对象的前一种方法在ECMAScript标准中是否有效并定义?前一种创建对象的方式与后一种创建方式有什么区别吗?是一个比另一个更好的选择吗?
new a.b()
与的不同之处new a().b()
在于,在前一种情况下,a.b
首先访问,而在后一种情况下,a
首先创建一个新。
Answers:
引用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权威指南:第四版》(第75页)
new Class
对于无参数构造函数,不要使用任何括号。如果这没有拼写为“ opinionated”,我不知道这是什么...
new Object.func()
不等同于new Object().func()
。通过始终加上括号,消除了犯此错误的可能性。
(new Object).func()
。但是我考虑使用额外的括号和额外的等号,例如==
vs中===
,这是不学习语言的不好借口。
两者之间有区别:
new Date().toString()
可以正常工作并返回当前日期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 Date().toString()
完美工作,因为它的评估为 (new Date()).toString()
new Date.toString()
抛出“ TypeError:Date.toString不是构造函数 ”,因为.
它的优先级高于new Date
(且高于“ Function Call”),并且表达式的计算结果为(new (Date.toString))()
相同的逻辑可以应用于… [ … ]
运算符。
new Foo
具有从右到左的关联性,对于new Foo()
“关联性”不适用。我认为在实践中没有任何区别。有关更多信息,请参阅本 SO问题
是一个比另一个更好的选择吗?
知道了所有这些,就可以认为这new Foo()
是首选。
new Foo()
应该优先于的原因new Foo
。迄今为止最好的答案。
new Object().something()
和撰写文章变得很不错(new Object()).something()
。
(new Date).toString()
,字符数相同,并且比更加明确new Date().toString
。
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
这是ES6规范的一部分,它定义了两种变体的工作方式。无括号变体传递一个空的参数列表。
有趣的是,两种形式的语法含义不同。当您尝试访问结果成员时,将显示此消息。
new Array.length // fails because Array.length is the number 1, not a constructor
new Array().length // 0