Skip to content

如何正确判断相等性

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness

js
null == undefined // ture
null === undefined // false
null == undefined // ture
null === undefined // false

null与undefined

什么时候会出现null

  • 手动设置变量的值或者对象某一个属性值为null(此时不赋值,会在后面的代码中进行赋值,相当于初始化。)
  • 在JS的DOM元素获取中,如果没有获取到指定的元素对象,结果一般是null。
  • js正则表达式的 match方法,如果匹配不到就会返回null。
  • 在正则捕获的时候,如果没有捕获到结果,默认也是null。

什么情况会出现undefined

  • 在变量提升(预解析)阶段,只声明未定义,默认值就是undefined。
  • 在JS的严格模式下(“use strict”),没有明确的主体,this指的就是undefined。
  • 函数定义没有返回值(return或者return后面什么也不带),默认的返回值就是undefined。
  • 函数定义形参不传值,默认就是undefined。
  • 对象没有这个属性名,属性值默认就是undefined。
  • 在数组的find方法中,没有找到的情况下是undefined。
  • Object.prototype._proto_的值也是undefined。
  • 当我们使用?.获取对象属性时候获取不到也是undefined。
  • 当我们使用 new Map() 中的get() 获取的键名在Map集合中不存在时,会返回undefined。

null

  • null的性质:一个语言关键字
  • 作用:用于表示某个值不存在
  • 对null使用typeof操作符返回字符串"object",表明可以将null看成一种特殊对象,表示“没有对象”

undefined

  • undefined的性质:一个预定义的全局常量,这个常量的初始化值就是undefined
  • 对undefined使用typeof操作符返回字符串"undefined",表示这个值是该特殊类型的唯一成员

异同

  • ==认为他们相等
  • 他们都是假性值
  • null表示程序级别、正常或意料之中的没有值
  • undefined表示系统级别、意料之外或类似错误的没有值

探究==和=== (== 中的隐式强制类型转换)

js
{ // null 
      console.log(null == null)
      console.log(null == undefined)
      console.log(null == false)
      console.log(null == '')
      console.log(null == 0)

      console.log(null === null)
      console.log(null === undefined)
      console.log(null === false)
      console.log(null === '')
      console.log(null === 0)
    }

    { // undefined
      console.log(undefined == undefined)
      console.log(undefined == null)
      console.log(undefined == false)
      console.log(undefined == '')
      console.log(undefined == 0)
    }

    { // 数字和字符串
      console.log(123 == '123')
      console.log(123 === '123')
    }

    { // 布尔类型
      // 首先 b 是 boolean 类型, 所以 ToNumber(b) 将 b 的类型强制转换为 1, 变成 1 == '77', 二者的类型仍然不同, "77" 根据规则被强制类型转换为 77, 最后变成 1 == 77, 所以结果输出为 false;
      console.log(true == '123', '!')
      console.log(true == '1', '!')
      console.log(true == 1, '!')

      console.log(true === '123')
      console.log(true === '1')
      console.log(true === 1)
    }

    {

      console.log(77 == [77], '??')
      console.log('abc' == Object('abc'))
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
    }

    { // ==中的隐式强制类型转换最为让人不满的地方是假值的相等比较下面分别列出了常规和非常规的情况:
      console.log("0" == null); // false
      console.log("0" == undefined); // false
      console.log("0" == false); // true
      console.log("0" == NaN); // false
      console.log("0" == 0); // true
      console.log("0" == ""); // false

      console.log(false == null); // false
      console.log(false == undefined); // false
      console.log(false == NaN); // false
      console.log(false == 0); // true
      console.log(false == ""); // true
      console.log(false == []); // true
      console.log(false == {}); // false

      console.log("" == null); // false
      console.log("" == undefined); // false
      console.log("" == NaN); // false
      console.log("" == 0); // true
      console.log("" == []); // true
      console.log("" == {}); // false

      console.log(0 == null); // false
      console.log(0 == undefined); // false
      console.log(0 == NaN); // false
      console.log(0 == []); // true
      console.log(0 == {}); // false

    }
{ // null 
      console.log(null == null)
      console.log(null == undefined)
      console.log(null == false)
      console.log(null == '')
      console.log(null == 0)

      console.log(null === null)
      console.log(null === undefined)
      console.log(null === false)
      console.log(null === '')
      console.log(null === 0)
    }

    { // undefined
      console.log(undefined == undefined)
      console.log(undefined == null)
      console.log(undefined == false)
      console.log(undefined == '')
      console.log(undefined == 0)
    }

    { // 数字和字符串
      console.log(123 == '123')
      console.log(123 === '123')
    }

    { // 布尔类型
      // 首先 b 是 boolean 类型, 所以 ToNumber(b) 将 b 的类型强制转换为 1, 变成 1 == '77', 二者的类型仍然不同, "77" 根据规则被强制类型转换为 77, 最后变成 1 == 77, 所以结果输出为 false;
      console.log(true == '123', '!')
      console.log(true == '1', '!')
      console.log(true == 1, '!')

      console.log(true === '123')
      console.log(true === '1')
      console.log(true === 1)
    }

    {

      console.log(77 == [77], '??')
      console.log('abc' == Object('abc'))
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
      console.log()
    }

    { // ==中的隐式强制类型转换最为让人不满的地方是假值的相等比较下面分别列出了常规和非常规的情况:
      console.log("0" == null); // false
      console.log("0" == undefined); // false
      console.log("0" == false); // true
      console.log("0" == NaN); // false
      console.log("0" == 0); // true
      console.log("0" == ""); // false

      console.log(false == null); // false
      console.log(false == undefined); // false
      console.log(false == NaN); // false
      console.log(false == 0); // true
      console.log(false == ""); // true
      console.log(false == []); // true
      console.log(false == {}); // false

      console.log("" == null); // false
      console.log("" == undefined); // false
      console.log("" == NaN); // false
      console.log("" == 0); // true
      console.log("" == []); // true
      console.log("" == {}); // false

      console.log(0 == null); // false
      console.log(0 == undefined); // false
      console.log(0 == NaN); // false
      console.log(0 == []); // true
      console.log(0 == {}); // false

    }