JavaScript ECMA-ES3 相等(==)和嚴格相等(===)運算子詳解
本文以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、總結
相等( == )和嚴格相等( === ,有的地方也稱恆等),兩者最大的區別就是相等運算子可能會進行型別轉換,嚴格相等不會進行型別轉換。