参考链接

阮大JS教程:null, undefined 和布尔值

阮大博客:undefined与null的区别

深入探究:null 和 undefined 究竟有何区别?

null 与 undefined

总的来说,

null 表示一个 “空值” 的对象,但它不是一个空对象,因为它根本就没有属性;

undefined 表示 “缺少值”,就是此处应该有一个值,但是还没有定义。

主要区别就是,null 表示有值但为空,undefined 表示没有值。

关于它们的一些具体表现,比如说转为数值的时候,null 转为 0undefined 转为 NaN

使用 typeof 的时候,会分别返回 nullundefined

区别表现

转为数值

  1. Number(null) // 0
  2. 5 + null // 5
  3. Number(undefined) // NaN
  4. 5 + undefined // NaN

两者不严格相等

  1. undefined == null // true
  2. undefined === null // false

使用 **typeof**

  1. typeof null // 'object'
  2. typeof undefined // 'undefined'

典型场景

**null** 表示 “空” 的对象,即该处不应该有值。典型场景是:

(1)作为函数的参数,表示该函数的参数不是对象。

(2)作为对象原型链的终点。

**undefined** 表示 “缺少值”,就是此处应该有一个值,但是还没有定义。典型场景是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2)调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

使用

**null** 表示一个值被定义了,定义为“空值”;

**undefined** 表示根本不存在定义。

所以设置一个值为 null 是合理的,如 objA.valueA = null;

但设置一个值为 undefined 是不合理的

  1. objA.valueA = undefined; // 应该直接使用 delete objA.valueA;

任何一个存在引用的变量值为 undefined 都是一件错误的事情。

这样判断一个值是否存在,就可以用

  1. objA.valueA === undefined // 不应使用 null

因为 undefined == null(不是严格相等),而 null 表示该值定义为空值

其他

为什么 typeof nullobject

typeof null 输出为 'object' 其实是一个底层的错误,但直到现阶段都无法被修复。

原因是,在 JavaScript 初始版本中,值以 32位 存储。前 3位 表示数据类型的标记,其余位则是值。
对于所有的对象,它的前 3位 都以 000 作为类型标记位。在 JavaScript 早期版本中, null 被认为是一个特殊的值,用来对应 C 中的 空指针 。但 JavaScript 中没有 C 中的指针,所以 null 意味着什么都没有或者 void 并以 全0(32个) 表示。

因此每当 JavaScript 读取 null 时,它前端的 3位 将它视为 对象类型 ,这也是为什么 typeof null 返回 'object' 的原因。

为什么 ===== 对比会出现 truefalse

很多文章说: undefined 的布尔值是 falsenull 的布尔值也是 false ,所以它们在比较时都转化为了 false ,所以 undefined == null
实际上并不是这样的。
ECMA11.9.3 章节中明确告诉我们:

  1. If x is null and y is undefined, return true.
  2. If x is undefined and y is null, return true.

这是 JavaScript 底层的内容了,至于更深入的内容,,如果有兴趣可以扒一扒 JavaScript 的源码。

为什么 let undefiend = 'test' 可以覆盖掉 JavaScript 自身的 undefined

  1. function test(n) {
  2. let undefined = 'test'
  3. return n === undefined
  4. }
  5. test() // false
  6. test(undefined) // false
  7. test('test') // ture
  8. let undefined = 'test' // Uncaught SyntaxError: Identifier 'undefined' has already been declared

JavaScript 对于 undefined 的限制方式为全局创建了一个只读的 undefined ,但是并没有彻底禁止局部 undefined 变量的定义。

据说在 JavaScript 高版本禁止了该操作,但我没有准确的依据。

请在任何时候,都不要进行 undefined 变量的覆盖,就算是你的 JSON 转换将 undefined 转换为 '' 。也不要通过该操作进行,这将是及其危险的行为。