== 和===运算符,分别在什么情况下使用?有什么区别?🔥🔥🔥

441 阅读5分钟

JavaScript提供了两种相等的运算符:=====

一、相等(==)运算符

  • 相等(==)运算符用来比较相同类型的数据时,与严格相等(===)运算符完全一样。
  • 比较不同类型的数据时,相等(==)运算符会先将数据进行类型转换,然后再用严格相等(===)运算符比较。

比较时,会遵循以下的规则:

  1. 如果比较的两个操作数中,有一个操作数是 布尔值 或者 字符串,则尝试将布尔值和字符串转换为数值后,再比较两个操作数是否相等。
const result1 = (true == 1)          // true
const result2 = (true == "1")        // true
const result3 = (false == 0)         // true
const result4 = (false == "0")       // true
const result5 = (true == "")         // false
const result6 = (false == "")        // true
  1. 如果一个操作数是 字符串,另一个操作数是 数值,则尝试将字符串转换为数值后,再比较两个操作数是否相等。
const result1 = ("1" == 1)  // true
const result2 = ("0" == 0)  // true
  1. nullundefined 比较时,结果为 truenullundefined 与其它类型的值比较时,结果为 false
const result1 = (null == undefined)     // true
const result2 = (0 == null)             // false
const result3 = (0 == undefined)        // false
const result4 = (true == null)          // false
const result5 = (true == undefined)     // false
const result6 = ("" == null)            // false
const result7 = ("" == undefined)       // false
  1. 如果有一个操作数是 NaN ,则两个操作数比较的结果返回 false
const result1 = (true == "true")     // false
// 等同于 Number(true) === Number("true")
// 等同于 1 === NaN

const result2 = (NaN == NaN)         // false
  1. 如果两个操作数都是对象(这里的对象指广义的对象,包括数组和函数),则比较它们是不是同一个对象。如果两个对象都指向同一个内存地址,则相等操作符返回 true
const obj1 = { name: "Oct13_JJP" }
const obj2 = { name: "Oct13_JJP" }
const result1 = (obj1 == obj2)         // false

const obj3 = { name: "Oct13_JJP" }
const obj4 = obj3
const result2 = (obj3 == obj4)         // true

二、严格相等(===)运算符

  1. 如果两个操作数的类型不同,直接返回 false
const result1 = (true === "true")  // false
const result2 = (1 === "1")        // false
  1. 如果两个操作数的类型相同,值也相同,则返回 true
const result1 = (1 === 1)    // true
const result2 = (1 === 0x1)  // true 
// 上面代码中,0x1是十六进制的1,与十进制的1比较,因为数据类型相同,值也相同,所以返回 true
  1. nullundefined 与自身严格相等。
const result1 = (null === null)              // true
const result2 = (undefined === undefined)    // true
  1. 变量声明后默认值是 undefined,因此两个只声明未赋值的变量是相等的。
let v1, v2;
let result1 = (v1 === v2)  // true
  1. 两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个地址。
const obj1 = {}
const obj2 = {}
const result1 = (obj1 === obj2)                 // false

const arr1 = []
const arr2 = []
const result2 = (arr1 === arr2)                 // false

const fun1 = () => {}
const fun2 = () => {}
const result3 = (fun1 === fun2)                 // false

上面的代码分别比较两个空对象obj1和obj2、两个空数组arr1和arr2、两个空函数fun1和fun2,结果都是false。原因是:对于复合类型的值,严格相等运算比较的是,它们是否引用同一个内存地址,而运算符两边的空对象、空数组、空函数的值,都存放在不同的内存地址,所以结果是 false

  1. 如果两个变量引用同一个对象,则用严格相等运算比较时,结果是 true
const obj1 = {}
const obj2 = obj1
const result1 = (obj1 === obj2)          // true

const arr1 = []
const arr2 = arr1
const result2 = (arr1 === arr2)          // true

const fun1 = () => {}
const fun2 = fun1
const result3 = (fun1 === fun2)          // true
  1. 注意:

NaN 与任何值都不相等(包括自身)。

const result1 = (NaN === NaN)            // false

0 等于负 0

const result1 = (+0 === -0)              // true

对于两个对象的比较,严格相等运算符比较的是地址,而大于或小于运算符比较的是值。

new Date() > new Date()                  // false
new Date() < new Date()                  // false
new Date() === new Date()                // false

三、总结

  • 相等(==)运算符

    • 如果两个操作数都为简单类型,字符串和布尔值会先转换成对应的数值,再进行比较
    • 如果简单类型与引用类型比较,对象转化成其原始类型的值,再比较
    • 如果两个操作数都为引用类型,则比较它们是否指向的是同一个内存地址
    • null 和 undefined 相等
    • 存在 NaN 则返回 false
  • 严格相等(===)运算符

    • 如果两个操作数的类型不同,比较的结果就是 false。
    • 如果两个操作数都是 null 或都是 undefined,比较的结果是 true。
    • 如果两个操作数是数字,并且值相同,除非其中一个或两个都是 NaN (这种情况下比较,结果是 false),否则它们是等同的。值 NaN 不会与其他任何值等同,包括它自身。
    • 如果两个操作数都是字符串,而且在字符串中同一位置上的字符完全相同,那么它们就完全等同。如果字符串的长度或内容不同,它们就不是等同的。
    • 如果两个操作数都是布尔型 true,或者两个操作数都是布尔型 false,那么它们等同。
    • 如果两个操作数引用的是同一个对象、数组或函数,那么它们完全等同。如果它们引用的是不同的对象、数组或函数,它们就不完全等同,即使这两个对象具有完全相同的属性,或两个数组具有完全相同的元素。
    • null 和 undefined 严格相等

四、什么情况下使用 == 和 === 运算符

  1. 相等运算符隐藏的类型转换,会带来一些违反直觉的结果。
0 == ''             // true
0 == '0'            // true

2 == true           // false
2 == false          // false

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true
  1. 在比较值是否等于 null 的情况的时候,我们一般使用相等运算符(==)。.
const obj = {};
if(obj.name == null){
  console.log("该语句被执行");     // 该语句被执行
}

// 上面的代码等同于
const obj = {};
if(obj.name === null || obj.name === undefined) {
  console.log("该语句被执行");     // 该语句被执行
}

  1. 因此,除了在比较对象属性为 null 或者 undefined 的情况下,我们可以使用相等运算符(==),其他情况建议使用严格相等运算符(===)。

参考文章:JavaScript标准参考教程(alpha)