本文以JavaScript ES3为例谈谈相等( == )运算符、严格相等( === )运算符判断逻辑,探探其背后到底是怎么工作的。
1、抽象相等 ==
参考ECMA-262-3说明,The comparison x == y, where x and y are values, produces true or false. Such a comparison is
performed as follows:
- If Type(x) is different from Type(y), go to step 14.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is not Number, go to step 11.
- If x is NaN, return false.
- If y is NaN, return false.
- If x is the same number value as y, return true.
- Ifxis+0andyis−0,returntrue.
- Ifxis−0andyis+0,returntrue.
- Return false.
- If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
- If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
- Return true if x and y refer to the same object or if they refer to objects joined to each other (see13.Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false.
- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
- If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
- If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
- Return false.
一个简单的 == 运算符,其背后有22步,真是看似简单其实一点也不简单呢,下面我们以几个demo来讲解 == 运算符到底是怎么工作的,demo来自《JavaScript权威指南 第6版》
案例1:
null == undefined // true
说明:
1、Type(null) = Null, Type(undefiend) = Undefiend,两者不等,跳到14
14、If x is null and y is undefined, return true,满足要求,返回true,比较结束
案例2:
"0" == 0 // true
说明:
1、Type(“0”) = String, Type(0) = Number,两者不等,跳到14
14、If x is null and y is undefined, return true,不满足
15、If x is undefined and y is null, return true,不满足
16、If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y),不满足
17、If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y. 符合条件,ToNumber(“0”) = 0, 转换成 0 == 0,进行新一轮比较。
1、Type(0) = Number, Type(0) = Number,两者相等,继续判断
2、If Type(x) is Undefined, return true,不满足,继续
3、If Type(x) is Null, return true,不满足,继续
4、If Type(x) is not Number, go to step 11,不满足,继续
5、If x is NaN, return false,不满足,继续
6、If y is NaN, return false,不满足,继续
7、If x is the same number value as y, return true,满足,返回true,结束
案例3:
0 == false // true
说明:
1、Type(0) = Number, Type(false) = Boolean,两者不等,跳到14
14、If x is null and y is undefined, return true,不满足
15、If x is undefined and y is null, return true,不满足
16、If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y),不满足
17、If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y,不满足
18、If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y,不满足
19、If Type(y) is Boolean, return the result of the comparison x == ToNumber(y),满足,ToNumber(false) = 0,变成 0 == 0,同案例2的新一轮比较,返回true
案例4:
"0" == false // true
说明:
1、Type(0) = Number, Type(false) = Boolean,两者不等,跳到14
14、If x is null and y is undefined, return true,不满足
15、If x is undefined and y is null, return true,不满足
16、If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y),不满足
17、If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y,不满足
18、If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y,不满足
19、If Type(y) is Boolean, return the result of the comparison x == ToNumber(y),满足,ToNumber(false) = 0,变成 “0” == 0,同案例2,返回true
2、严格相等 ===
参考ECMA-262-3说明,The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is not Number, go to step 11.
- If x is NaN, return false.
- If y is NaN, return false.
- If x is the same number value as y, return true.
- Ifxis+0andyis−0,returntrue.
- Ifxis−0andyis+0,returntrue.
- Return false.
- If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
- If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
- Return true if x and y refer to the same object or if they refer to objects joined to each other (see13.Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false.
看几个案例,进一步说明:
案例1:
null === undefined // false
说明:
1、Type(null) = Null, Type(undefiend) = Undefiend,两者不等,满足要求,返回false,结束.
案例2:
"0" === 0 // false
说明:
1、Type(“0”) = String, Type(0) = Number,两者不等,满足要求,返回false,结束.
案例3:
var a = 1, b = Number(1);
console.log(a===b); //true
说明:
1、Type(a) = Number, Type(b) = Number,两者相等,不满足,继续.
2、If Type(x) is Undefined, return true,不满足,继续
3、If Type(x) is Null, return true,不满足,继续
4、If Type(x) is not Number, go to step 11,不满足继续
5、If x is NaN, return false,不满足,继续
6、If y is NaN, return false,不满足,继续
7、If x is the same number value as y, return true,满足,返回true,结束
案例4:
var a = '123', b = String('123');
console.log(a===b); //true
说明:
1、Type(a) = String, Type(b) = String,两者相等,不满足,继续.
2、If Type(x) is Undefined, return true,不满足,继续
3、If Type(x) is Null, return true,不满足,继续
4、If Type(x) is not Number, go to step 11,满足,跳到11
11、If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false,字符串’123’,'123’长度和序列都一致,因此返回true,结束。
案例5:
var a = {name:'marcus'}, b = {name:'marcus'};
console.log(a==b); //false
说明:
1、Type(a) = Object, Type(b) = Object,两者相等,不满足,继续.
2、If Type(x) is Undefined, return true,不满足,继续
3、If Type(x) is Null, return true,不满足,继续
4、If Type(x) is not Number, go to step 11,满足,跳到11
11、If Type(x) is String,不满足,继续
12、If Type(x) is Boolean,不满足,继续
13、Return true if x and y refer to the same object or if they refer to objects joined to each other (see13.Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false,
满足,a和b都是新建的对象,两者不是指向同一个对象,因此返回false,结束
3、总结
相等( == )和严格相等( === ,有的地方也称恒等),两者最大的区别就是相等运算符可能会进行类型转换,严格相等不会进行类型转换。