JavaScript中有两种相等运算符:==
和===
。它们的比较规则如下:
==
是抽象相等运算符,它会在比较之前,尝试将两个操作数转换成相同的类型,然后再比较它们的值是否相等。例如,1 == "1"
会返回true,因为字符串"1"会被转换成数字1,然后再比较。===
是严格相等运算符,它不会进行类型转换,而是直接比较两个操作数的类型和值是否完全相同。例如,1 === "1"
会返回false,因为数字1和字符串"1"的类型不同,就算它们的值相同也不会返回true。
一般来说,建议使用===
来进行比较,因为它可以避免一些意想不到的结果,例如:
null == undefined
会返回true,但是null === undefined
会返回false。0 == false
会返回true,但是0 === false
会返回false。NaN == NaN
会返回false,但是NaN === NaN
也会返回false。
抽象相等运算符在尝试将两个操作数转换成相同的类型时,会遵循以下的规则:
- 如果两个操作数都是原始类型,那么会按照以下的顺序进行类型转换:
- 如果一个操作数是布尔值,那么会把它转换成数字,true转换成1,false转换成0。
- 如果一个操作数是字符串,另一个操作数是数字,那么会把字符串转换成数字。
- 如果一个操作数是null,另一个操作数是undefined,那么不进行类型转换,直接返回true。
- 如果一个操作数是null或undefined,另一个操作数是非null或非undefined的原始值,那么不进行类型转换,直接返回false。
- 如果两个操作数都是字符串,那么不进行类型转换,直接比较它们的字面值是否相等。
- 如果两个操作数都是数字,那么不进行类型转换,直接比较它们的数值是否相等(注意NaN和任何值都不相等)。
例如:"1" == true
会返回true,因为true会转换成1,然后字符串"1"也会转换成1,所以两个1相等;同理,"0" == false
也会返回true
- 如果两个操作数中有一个是对象类型,另一个是原始类型,那么会把对象类型的操作数转换成原始类型,然后再进行比较。对象类型的操作数会调用它的valueOf()方法或toString()方法(如果valueOf()方法不存在或返回的不是原始值),来得到一个原始值。例如,
[1,2,3] == "1,2,3"
会返回true,因为数组会调用toString()方法返回字符串"1,2,3"。 - 如果两个操作数都是对象类型,那么不进行类型转换,直接比较它们的引用是否相同。也就是说,只有当两个对象指向同一个内存地址时,才会返回true。例如,
[1,2,3] == [1,2,3]
会返回false,因为它们是两个不同的数组对象。