概述: 使用
==
进行比较,当两个比较元类型不同时,会事先进行类型转换。(这也是其与===
的本质区别)
转换规则:
- 当只有一方是
boolean
时,先将boolean
转number
。(true: 1
,false: 0
)- 当一方
number
一方string
时,string
转number
。(Number(string)
, 结果可能是NaN
)- 当只有一方是
object
时,object
调用valueOf()
获取其原始值
(1)若valueOf()
方法返回值的类型不是对象(null
除外),则使用该返回值继续进行 1. 2. 的判断
(2)否则,object
调用toString()
获取其返回值
(2-1)若toString()
方法返回值的类型不是对象,则使用该返回值继续进行 1. 2. 的判断
(2-2)否则,直接返回 false
这一部分看不懂的话,可以看看后边的第一点的示例比较规则:
undefined == null
为 true- 在与
undefined
和null
比较前,另外一个元不会进行类型转换- 两个
object
比较时,只有两个对象相同(也就是其值是同一个指针或者说对同一个对象的引用),==
才会返回 true。例如:{} == {}
返回 false。NaN
不与任何值相等,包括它自己(NaN == NaN
返回 false)
一、转换规则3的举例说明
let o = {};
// eg1:
o.valueOf = () => 1;
o.toString = () => 2;
o == 1; // true
o == 2; // false
// eg2:
o.valueOf = () => { return []; }
o.toString = () => 2;
o == 2; // true
o == []; // false,这时使用的是比较规则3,两个对象比较,判断指针是否相同
// eg3:
o.valueOf = () => { return null; } // return undefined 也是同样道理
o.toString = () => 2;
o == 2; // false valueOf的返回值是null,不是普通对象,直接使用null了。null与2比较返回false
o == null; // false 此时使用的是比较规则2,object不进行类型转换
// eg4:
o.valueOf = () => { return []; }
o.toString = () => { return o; }
o == 任何非o的原始类型数据或对象 // false
o == o; // true 此时使用的是比较规则3,对象比较判断是否是同一对象(指针)
二、分析 [] == []
返回 false,[] == ![]
返回 true
-
[] == []
返回 falselet l1 = []; let l2 = []; // 因为 l1, l2 实际上是两个不同的对象(指针),根据比较规则 3 ,返回 false
-
[] == ![]
返回 truelet l1 = []; let l2 = []; /* 比较步骤 1. l1 == !l2 ? !l2 => ![] => false (! 优先级比 == 高) 2. l1 == false ? false => 0 (转换规则1,一方boolean,boolean转number) 3. l1 == 0 ? l1 => l1.valueOf() => [] => (非null对象,不行) => l1.toString() => "" (转换规则3,一方为对象时...) 4. "" == 0 ? "" => 0 (转换规则2,一方number一方string,string转number) 5. 0 == 0 ,返回true */
二、分析 {} == {}
、 {} == !{}
均返回 false
-
{} == {}
返回 falselet o1 = {}; let o2 = {}; // 因为 o1, o2 实际上是两个不同的对象(指针),根据比较规则 3 ,返回 false
-
{} == !{}
返回 falselet o1 = {}; let o2 = {}; /* 比较步骤 1. o1 == !o2 ? !o2 => !{} => false (! 优先级比 == 高) 2. o1 == false ? false => 0 (转换规则1,一方boolean,boolean转number) 3. o1 == 0 ? o1 => o1.valueOf() => {} => ({}是对象,不行) => o1.toString() => '[object object]' (转换规则3,一方为对象时...) 4. '[object object]' == 0 ? '[object object]' => NaN (转换规则2,一方number一方string,string转number) 5. NaN == 0 返回 false (比较规则4,NaN不与任何值相等) */