如果([] == false)为真,为什么([] || true)会导致[]?

时间:2014-08-12 19:33:05

标签: javascript comparison truthiness

刚做了一些测试,我发现这很奇怪:

[] == false

这是正确的,这是有道理的,因为double equal只比较内容而不是类型并尝试进行类型强制。但是如果它比较内容并返回true,那意味着[]是假的(如果你[] == true你也会得到假),这意味着:

[] || false

应该给出错误,但它会给[],使它变得真实吗?为什么呢?

另一个例子:

"\n  " == 0

给出了真实,但"\n " || false给出了"\n "?有没有解释这个或它只是一个奇怪的。

当我在C中尝试这个时,我们得到:

int x = "\n " == 0;
printf("%d\n", x);

int y = "\n " || 0;
printf("%d\n", y);

输出:

0
1

这是有道理的,但考虑到C对Javascript的影响,行为是不同的。

3 个答案:

答案 0 :(得分:3)

“是假的”(即使是强制)也不同于“在布尔上下文中评估为假”。 obj == false询问对象布尔值false,而不是它是否会在布尔上下文中进行评估时进行评估。

您可以使用(!!obj)评估布尔上下文中的对象。

[] == false;         // true
(!![]) == false;     // false

"\n  " == false;     // true
(!!"\n  ") == false; // false

答案 1 :(得分:3)

类型转换与假值和真值无关。

什么是真实的,什么是假的是由规范中定义的ToBoolean函数定义的[]确实是真实的。

另一方面,[] == false会返回true,因为在评估表达式时会发生type conversion

类型转换规则适用于x == y

  

如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。

ToNumber导致0为false,因此我们留下了[] == 0的评估。根据相同的规则

  

如果Type(x)是Object而Type(y)是String或Number,则返回比较结果ToPrimitive(x)== y。

ToPrimitive会产生一个空字符串。现在我们有"" == 0。返回我们的类型转换规则

  

如果Type(x)是String而Type(y)是Number,   返回比较结果ToNumber(x)== y。

ToNumber导致""为0,因此最终评估为0 == 0,即true

答案 2 :(得分:0)

来自ECMA-262 5.1(第83页)的

  

如果ToBoolean(lval)为true,则返回lval

[] || false; // []