宽松相等和严格相等

常见的误区是:“== 检查值是否相等,=== 检查值和类型是否相等”

正确的解释是:“== 允许在相等比较中进行强制类型转换,而=== 不允许。”

抽象相等比较算法

ES5规范11.9.3节对抽象相等比较算法定义如下: ES5规范

以 x 和 y 为值进行 x == y 比较会产生的结果可为 true 或 false。比较的执行步骤如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.Type(x) 与 Type(y) 相同, 则
1.Type(x) 为 Undefined, 返回 true
2.Type(x)为 Null, 返回 true
3.Type(x)为 Number,则
1. 若 x 为 NaN,返回 false
2. 若 y 为 NaN,返回 false
3. 若 x 与 y 为相等数值,返回 true
4. 若 x 为 +0 且 y 为 −0,返回 true
5. 若 x 为 −0 且 y 为 +0,返回 true
6. 返回 false
4.Type(x) 为 String,则当 x 和 y 为完全相同的字符序列(长度相等且相同字符在相同位置)时返回 true。否则,返回 false
5.Type(x) 为 Boolean,当 x 和 y 为同为 true 或者同为 false 时返回 true。否则,返回 false
当 x 和 y 为引用同一对象时返回 true。否则,返回 false
2. 若 x 为 null 且 y 为 undefined,返回 true
3. 若 x 为 undefined 且 y 为 null,返回 true
4.Type(x) 为 Number 且 Type(y) 为 String,返回 x == ToNumber(y) 的结果。
5.Type(x) 为 StringType(y) 为 Number,返回比较 ToNumber(x) == y 的结果。
6.Type(x) 为 Boolean,返回比较 ToNumber(x) == y 的结果。
7.Type(y) 为 Boolean,返回比较 x == ToNumber(y) 的结果。
8.Type(x) 为 String 或 Number,且 Type(y) 为 Object,返回比较 x == ToPrimitive(y) 的结果。
9.Type(x) 为 Object 且 Type(y) 为 String 或 Number,返回比较 ToPrimitive(x) == y 的结果。
10. 返回 false
注:根据上述等于的定义:
- 字符串比较可以以:"" + a == "" + b 硬性触发。
- 数值比较可以以:+a == +b 硬性触发。
- 布尔比较可以以:!a == !b 硬性触发。
注:等于运算符有以下的不变量:
- A != B 与 !(A == B) 相等。
- 除了 A 与 B 的执行顺序以外,A == B 与 B == A 相等。
注:等于运算符不总是可传递。举例来说,两个代表相同 String 值但是不同的 String 对象会分别与 String 值 ==,但是两个对象间不相等。
  1. 字符串和数字之间的相等:调用ToNumber(),将字符串转换为数字类型
  2. 其他类型和布尔类型之间的相等:调用ToNumber(),将布尔类型转换为数字类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var a = "42";
    强制类型转换 | 81
    // 不要这样用,条件判断不成立:
    if (a == true) {
    // ..
    }
    // 也不要这样用,条件判断不成立:
    if (a === true) {
    // ..
    }
    // 这样的显式用法没问题:
    if (a) {
    // ..
    }
    // 这样的显式用法更好:
    if (!!a) {
    // ..
    }
    // 这样的显式用法也很好:
    if (Boolean( a )) {
    // ..
    }
  3. null 和undefined 之间的相等:null==undefined 返回true

  4. 对象和非对象之间的相等:调用ToPrimitive()方法,将对象转为标量基本类型。

为了将值转换为相应的基本类型值,抽象操作ToPrimitive会首先检查该值是否有valueOf() 方法。
如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用toString()的返回值(如果存在)来进行强制类型转换。如果valueOf() 和toString() 均不返回基本类型值,会产生TypeError 错误。

Object valueOf()返回值 toString()返回值
数组Array 返回数组实例 将Array的元素转为字符串,用逗号分隔
布尔值Boolean 布尔值 转换为”true”或”false”
日期Date 从1970年到目前的时间(毫秒) 返回日期的文本表示形式。
函数Function 函数本身 返回如下格式字符串:function Name(){[native code]}
数字Number 数字值 返回数字文本形式
对象Object 对象本身,默认值 返回”[object objectname]”,objectname为对象类型的名称
字符串String 字符串值 返回String对象的值

严格等于比较算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
比较 x === y,x y 为值,需要产出 true false。比较过程如下:
1. 如果 Type(x) Type(y) 的结果不一致,返回 false
2. 如果 Type(x) 结果为 Undefined,返回 true
3. 如果 Type(x) 结果为 Null,返回 true
4. 如果 Type(x) 结果为 Number,则
a. 如果 x NaN,返回 false
b. 如果 y NaN,返回 false
c. 如果 x y 为同一个数字,返回 true
d. 如果 x +0,y -0,返回 true
e. 如果 x -0,y +0,返回 true
f. 返回 false
5. 如果 Type(x) 结果为 String,如果 x y 为完全相同的字符序列(相同的长度和相同的字符对应相同的位置),返回 true,否则,返回 false
6. 如果 Type(x) 结果为 Boolean,如果 x y 都为 true false,则返回 true,否则,返回 false
7. 如果 x y 引用到同一个 Object 对象,返回 true,否则,返回 false
坚持原创技术分享,您的支持将鼓励我继续创作!