console.log( 0 == '0' ); // true
console.log( 0 == [] ); // true
console.log( [] == '0' ); // false
为什么JavaScript会这样评估表达式?
console.log( 0 == '0' ); // true
console.log( 0 == [] ); // true
console.log( [] == '0' ); // false
为什么JavaScript会这样评估表达式?
当使用双等号操作符(==
)时,JavaScript会尝试强制类型转换。具体细节请参见规范:第11.9.3节:抽象相等比较算法。
示例1:
console.log( 0 == '0' ); // true
JavaScript将字符串强制转换为数字0
,因此0 == 0
。
示例2:
console.log( 0 == [] ); // true
0 == 0
。 console.log( [] == '0' ); // false
console.log( [] == '' ); // true
第一个看起来与先前的示例非常相似,但两侧都不是数字。乍一看,这似乎是一种真值比较,但是[]
并不是八个falsy
值之一。
[]
为真值,但''
为假值:
console.log( [] ? true : false ); // true
console.log( '' ? true : false ); // false
[] == ''
应该是false
。但正如我们之前所看到的,在JavaScript中并非如此!令人费解的是,使用==
时,[]
会转换为false
: console.log( [] == true ); // false
console.log( [] == false ); // true
[]
转换为 true
,因为它不是八个假值之一)。 相反,使用 ==
时,[]
转换为 false
。 console.log( [] == '0' ); // `false == true`, so false
console.log( [] == '' ); // `false == false`, so true
示例 4:
console.log( [0] == '' ); // false
console.log( [1] == '' ); // false
例子5:
console.log( [0] == '0' ); // true
console.log( [0] == '1' ); // false
console.log( [1] == '1' ); // true
console.log( [1] == '0' ); // false
console.log( [2] == '2' ); // true
console.log( [1] == '2' ); // false
当将只包含一个数字的数组与非空字符串进行比较时,令人惊讶的是,它会被转换为该数字。然后根据比较数字和字符串的规则,将字符串转换为数字。因此,我们在将(0
或1
或..)与(0
或1
或..)进行比较。
这是否是规范中的歧义?不同的实现之间有所不同吗?
在2020年10月27日于Windows 10上使用Chrome,在alert
而不是console.log
中进行的测试,网址为https://www.webtoolkitonline.com/javascript-tester.html
。
示例6:
如果以上所有内容都没有使您坚决不再使用==
,请考虑以下情况:
var a = [];
console.log( a == a ); // true
但是:
console.log( [] == [] ); // false
规范中的9种类型转换规则均不适用,因此这是第10种情况:尽管它们都没有任何内容,但它们不是相同的对象。 它们是空数组的两个不同实例。
总的来说,使用三等号进行类型和相等性检查通常更安全。
A handy illustration (for the cases that test truthiness) below:
function truthyOrFalsy(val) {
return val ? "Truthy" : "Falsy";
}
console.log("empty array:", truthyOrFalsy([]));
console.log("number zero:", truthyOrFalsy(0));
console.log("string with a zero character:", truthyOrFalsy("0"));
16 == "0x10"
或NaN != "NaN"
。
2)真值/伪值不相关;事实上,[]
是真值。两者再次被转换为数字,您可以再次用16 == ["0x10"]
来查看。
3)再次真值/伪值不相关。两者都被转换为字符串,正如您可以看到的[1,2] == '1,2'
;空数组被转换为空字符串,这与只包含一个 0
的字符串不相等。 - ETHproductions/*
If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
*/
console.log( 0 == '0');
/*
If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
*/
console.log( 0 == [] );
/*
If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
*/
console.log( [] == '0');
source: http://es5.github.io/#x11.9.3
console.log( 0 == '0');
JavaScript使用强制转换将两个值转换为数字并进行比较。现在0 == 0,所以返回true。
在第二种情况下
console.log( 0 == [] );
两者都是假值(假值是指在布尔上下文中评估时转换为false的值)。因此,现在比较false == false,返回true值。
在第三种情况下
console.log( [] == '0');
[] 是假值而 '0' 是字符串,JS 无法强制将它们转换为可比较的类型。因此返回 false。
'0'
转换成数字而不是字符串。第二种情况将把数组转换为数字。第三种情况将把数组转换为字符串并进行比较。 https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 - Quentin
0
是假值,字符串"0"
不是。 - JamiecBoolean([])
returnstrue
, notfalse
- LiranC[] == false
和![] == false
。¯\(ツ)/¯ - Siguza