为什么(!+;[]+;[])是';正确';和(false+;[])是';假';用Javascript?
我正在查看语法,以了解下面下一个代码的定义: 常量v=(!+[]+[]); 常数c=(假+[]); 控制台日志(v); 控制台日志(c)代码> 常量v=(!+[]+[]); 常数c=(假+[]); 控制台日志(v);为什么(!+;[]+;[])是';正确';和(false+;[])是';假';用Javascript?,javascript,arrays,ecmascript-6,Javascript,Arrays,Ecmascript 6,我正在查看语法,以了解下面下一个代码的定义: 常量v=(!+[]+[]); 常数c=(假+[]); 控制台日志(v); 控制台日志(c) 常量v=(!+[]+[]); 常数c=(假+[]); 控制台日志(v); 控制台日志(c)这是因为当您尝试将运算符应用于不同的数据结构时,JavaScript引擎会应用 在第一种情况下,它的作用是: 将第一个[]转换为原语,这是通过调用数组的toString()方法执行的。toString方法将所有数组值连接到一个字符串。如果你有类似于(false+[1,2
控制台日志(c)代码>这是因为当您尝试将运算符应用于不同的数据结构时,JavaScript引擎会应用 在第一种情况下,它的作用是:
(false+[1,2,3])
的东西,你会得到:false 1,2,3
(!+[]+[])
计算为长度为4的“true”
这本书是了解JavaScript引擎所做的所有这些奇怪操作的宝库
编辑:正如Felix Kling所建议的那样!操作员在计算(!++[]+[])
时扮演不同的角色
在这种情况下,发生的情况是:
的计算结果为true。这是因为!+[]
将它们放在布尔上下文中,其中对[]应用[toNumber]操作,即!+[]
和0
为!0
真
的计算结果为true+[]
。这是因为,当您尝试向对象添加布尔值时(数组是从对象派生的)[toString]操作将应用于这两个项'true'
const v = (! + [] + []);
我们可以看到存在一个逻辑运算符(逻辑运算符不是!
),一个一元运算符(+
)和一个算术运算符,实际上是加法+
。如果我们考虑表达式的求值顺序,我们可以这样写:
const v = ( (!(+[])) + [] );
现在,这里计算的第一个表达式是+[]
,从操作符的文档中可以得到:
一元加号运算符位于其操作数之前,并计算为其操作数,但如果尚未将其转换为数字,则尝试将其转换为数字
实际上,前面的求值结果是0
(在将空数组强制转换为数字类型时会发生强制),您可以在下一个示例中查看:
console.log(+[])
查看规范中的+
运算符(它强制它的参数),请参阅此处的解释:“true”。length=4,“false”。length=5请参阅的可能重复,这些不是数组,而是字符串[]
确实是数组,但这些数组被转换成字符串。@t.niese“这些”指的是v
(true
)和c
(false
),而不是+
.FWIW,!+[1,2,3]
是否为真
<代码>
是一个运算符,不是一个值。@FelixKling第一句话你说得对。至于另一个,一次!我想你可以从这个角度把它看作一个值。“你可以从这个角度把它看作一个值”不,运算符不是值,而是对值进行操作。我之所以提到这一点,是因为您的示例似乎暗示
被转换为false
。我觉得这个答案忽略了的要点
作用于一元数加+[]
返回的数字,而是表示如果+
是加法运算符,则code>本身可以用作操作x+y
的一部分的值。事实并非如此。第一行应该是更多的(!(++])+[]
,这相当于!0+[]
。