空数组是假值,但 [] ? 0 : 1 的结果为0。

14
如果在JavaScript中空数组[]被认为是falsy的,那么为什么当它作为三元运算符中的谓词时,该运算符会评估为第一个选项?
console.log([] == false); // prints true
console.log([] ? 0 : 1);  // prints 0 !

3
你看过这个代码吗:console.log([]===false); - lucas
2
尝试使用[]===false进行检查。 - ojovirtual
1
请注意,[]===false是假的,但[]==false是真的。我猜这归结于JavaScript如何评估[]的类型。 - OliverRadini
1
你假设 if ([]) { } 等同于 if ([] == true) { },但在 JS 中并非如此,因为 == 在比较两个不同类型的操作数时具有非平凡的行为(请查看文档和 ojovirtual 的帖子)。 - Holt
@lucas []===falsefalse;这并不令人惊讶。 - Marcus Junius Brutus
显示剩余2条评论
3个回答

44

一个数组不是假值; 这可以使用 console.log(!![]) 来证明。

当通过 == 操作数进行左 vs. 右比较时,JavaScript 尝试将输入强制转换为一种公共类型。

对于你的第一个例子 [] == false,以下情况发生:

  1. 右侧被发现是 Boolean,因此将其转换为一个 Number 值,导致比较为 [] == 0
  2. 由于左侧是一个 Object,所以它被转换为一个基元;在这种情况下是通过 [].toString() 转换为一个 String,导致比较为 "" == 0
  3. 由于左侧是一个 String,它被转换为一个 number 值,导致 0 == 0
  4. 由于两个侧都是 Number 基元,它们的值被比较,结果为真值

对于第二个例子 [] ? 0 : 1,没有右侧值与之比较,因此它只是测试输入是否为真值。数组既不是 undefinednull0"" 或者 NaN,所以被视为真值,因此返回 'true' 选项:0;

如果要强制进行非强制转换的比较,请使用 === 操作数。

Ecma 标准第6版关于强制转换的条目
JS 强制转换解释


5
亲爱的JS,我不喜欢这个:(有太多底层强制转换会让我吃亏。 - Will

2

在上面的答案基础上添加...

要获取任何值的真正布尔值,您可以在其前面加上 !! (这样就不会遇到任何强制转换问题);

对于您的情况,您可以这样做:

console.log(!![] == false)   //logs false

2

仅供参考。

Javascript有两种类型的比较运算符:

  1. 严格比较 ===:检查类型和值

  2. 类型转换比较:== 只检查值。

尝试以下并检查结果:

console.log([] === false); //输出false console.log([] == false); //输出true console.log(0 == false); //输出true console.log(1 == "1") // 输出true console.log(1 === "1") //输出false

希望对你有所帮助。


1
这并没有解释发生这种情况的原因,它只是展示了=====之间的例子。 - SReject

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接