我刚刚做了一些测试,我发现这个奇怪的:
[] == false
返回true,这是有意义的,因为double equal只比较内容而不比较类型,并尝试进行类型强制转换。但如果它比较内容并返回真,这意味着[]是假的(如果你做了[] == true
,你也得到假),这意味着:
[] || false
应该给出假,但它给出[],使其为真?为什么?
另一个例子:
"n " == 0
为真,但"n " || false
为"n "
?这件事有什么解释吗?还是只是一件怪事?
当我在C中尝试时,我们得到:
int x = "n " == 0;
printf("%dn", x);
int y = "n " || 0;
printf("%dn", y);
输出:
0
1
这是有道理的,但考虑到C对Javascript的影响,行为是不同的。
类型转换与假值和真值无关。
真假由规范中定义的ToBoolean
函数定义,[]
确实为真。
另一方面,[] == false
返回true
,因为在表达式求值期间发生了类型转换。
类型转换规则规定,对于x == y
如果Type(y)为布尔值,则返回比较结果x == tonnumber (y)。
ToNumber
对于false的结果是0,所以我们剩下[] == 0
的求值。根据相同的规则
如果Type(x)为Object, Type(y)为String或Number,则返回比较的结果topprimitive (x) == y。
ToPrimitive
返回空字符串。现在我们有"" == 0
。回到类型转换规则
如果Type(x)为String, Type(y)为Number,返回比较的结果:number (x) == y
ToNumber
对""
的结果是0,所以最终的计算结果是0 == 0
,也就是true
!
"为假"(即使有强制转换)与"在布尔上下文中计算为假"不同。obj == false
询问对象是否是布尔值false
,而不是如果在布尔上下文中计算它是否会这样计算。
可以使用(!!obj)
对布尔上下文中的对象求值。
[] == false; // true
(!![]) == false; // false
"n " == false; // true
(!!"n ") == false; // false
来自ECMA-262 5.1 (page 83):
如果ToBoolean(lval)为真,返回lval
[] || false; // []