1. 程式人生 > >JavaScript ECMA-ES3 相等(==)和嚴格相等(===)運算子詳解

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:

  1. If Type(x) is different from Type(y), go to step 14.
  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.
  8. Ifxis+0andyis−0,returntrue.
  9. Ifxis−0andyis+0,returntrue.
  10. Return false.
  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.
  12. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
  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.
  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).
  20. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  21. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
  22. 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:

  1. If Type(x) is different from Type(y), return false.
  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.
  8. Ifxis+0andyis−0,returntrue.
  9. Ifxis−0andyis+0,returntrue.
  10. Return false.
  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.
  12. If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
  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.

看幾個案例,進一步說明:
案例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、總結

相等( == )和嚴格相等( === ,有的地方也稱恆等),兩者最大的區別就是相等運算子可能會進行型別轉換,嚴格相等不會進行型別轉換。