3

只是在做一些测试,我发现这很奇怪:

[] == false

给出 true,这是有道理的,因为 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 的影响,行为是不同的。

4

3 回答 3

4

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

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

另一方面,由于在表达式求值期间发生的类型转换[] == false而返回。true

类型转换的规则说,对于x == y

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

ToNumber结果为 0 表示假,所以我们只剩下[] == 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

于 2014-08-12T19:41:29.937 回答
3

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

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

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

"\n  " == false;     // true
(!!"\n  ") == false; // false
于 2014-08-12T19:35:56.400 回答
0

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

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

[] || false; // []
于 2015-05-21T20:20:12.463 回答