在Chrome JavaScript控制台中,为什么用括号包裹语句
{} - 0
可以改变返回值?{} - 0 // Returns -0
({} - 0) // Returns NaN
把一个语句用括号括起来就能改变其值,这看起来非常奇怪。我错过了什么吗?
{} - 0
可以改变返回值?{} - 0 // Returns -0
({} - 0) // Returns NaN
把一个语句用括号括起来就能改变其值,这看起来非常奇怪。我错过了什么吗?
这行代码{} - 0
有两种可能的解释:
{}; -0
,其中{}
被解释为空的块语句,而-
是一元否定运算符(因此-0
就是“负零”)。当计算其值时,它的值是最后一条语句的值,即-0。({} - 0)
,其中{}
被解释为空对象,而-
是减法运算符(因此从{}
中减去0
)。在第一行中,这是模棱两可的,所以会选择第一个解释。在第二行中,第一个解释无效(因为块语句永远不可能成为表达式的一部分,你正在强制使用括号)。
{}
解释为对象会怎样呢? 这对括号有效,但没有括号无效。(例如,使用括号,此表达式计算为3
:({valueOf:()=>3} - 0)
,但是没有括号,它仍然在控制台中返回 -0
: {valueOf:()=>3} - 0
)。这时候,添加的方法难道不应该强制将{..}
解释为对象,然后尝试进行减法运算吗? - Joseph Marikle{valueOf:()=>3}; -0
,但是({valueOf:()=>3}; -0)
是语法错误。 - Elliot GodzichvalueOf:
是一个标签语句(一种罕见的JavaScript特性),在语句() => 3;
之前,因此它仍然被解释为块语句而不是对象。
它被解释为{ valueOf: () => 3; }; -0
相同的方式。 - Frxstrem{ a: 1, b: 2 }
不能成为块语句,因为标签语句不能出现在逗号后面(因为它们不能成为表达式的一部分)。 - Frxstrem{valueOf:()=>3,a:0} - 0
。 - Joseph Marikle{} - 0
: 这里的 {}
只是一个什么也不做的空块,所以控制台返回了 -0
。
({} - 0)
: 这里的 {}
是表达式的一部分,并被转换为数字。在这个空对象中没有定义 valueOf()
方法,在转换为数字时,它会回退到 toString()
方法,对于 {}
返回类似于 object Object
的内容。然后,将这个字符串 object Object
转换为数字,由于它实际上不是一个数字,因此返回 NaN
。因此,我们有:
({} - 1)
-> ('object Object' - 1)
-> (NaN - 1)
任何与 NaN
相关的操作都会返回 NaN
,这就是最终在控制台中看到的结果。
{} - 0
被解释为:{} 空块语句
和 - 0 负零
({} - 0)
()
内的所有内容都被解释为一个表达式,空对象 - 0 = NaN