彻底搞懂 null 和 undefined!一次性解决所有疑惑,告别模糊认知

彻底搞懂 null 和 undefined!一次性解决所有疑惑,告别模糊认知

在 JavaScript 中,nullundefined 是两个常见但又容易混淆的概念。它们都表示“没有值”或“缺失的值”,但在具体语义和使用场景上存在细微而重要的差异。正因为这两者的模糊性,我包括身边的很多同事在工作甚至面试中经常对它们感到困惑,无法清楚地解释它们的含义或正确地判断它们的使用场景。所以今天特意就这个问题,花时间深入研究和理解了 nullundefined 的本质,写文章记录一下。


1. 什么是 null

1.1 定义

null 是一个特殊的值,表示“有意的空值”或“空对象”。它通常用来表示一个变量明确地没有值

1.2 特性

  • 数据类型:null 的类型是 “object” (这是一个 JavaScript 的设计错误,历史原因造成的)。

    console.log(typeof null); // 输出: "object"
    
  • 语义:null 表示一个变量当前没有值,但预期将来会被赋值。

1.3 使用场景

  • 初始化一个变量为空值:开发者用 null 来明确表示一个变量没有值。

    let value = null; // 表示 value 是空的,但以后可能会被赋值
    
  • 重置变量的值:用 null 将一个变量重置为空值。

    let user = { name: "Alice" };
    user = null; // 清空 user 对象,释放其引用
    
  • 函数的返回值:函数可以返回 null,表示明确没有结果。

    function findUser(id) {
      if (id !== 1) return null; // 返回 null 表示没有找到用户
      return { id: 1, name: "Alice" };
    }
    

2. 什么是 undefined

2.1 定义

undefined 是一个特殊值,表示“变量尚未被定义”或“未赋值”。

2.2 特性

  • 数据类型:undefined 的类型是 “undefined”

    console.log(typeof undefined); // 输出: "undefined"
    
  • 语义:undefined 表示一个变量还没有被赋值,或者表示某些操作没有返回值

2.3 使用场景

  • 未初始化的变量:声明了变量但没有赋值时,变量的值是 undefined

    let value;
    console.log(value); // 输出: undefined
    
  • 访问对象中不存在的属性:当尝试访问对象中不存在的属性时,返回 undefined

    const obj = {};
    console.log(obj.name); // 输出: undefined
    
  • 函数中未指定返回值:如果函数没有显式返回值,默认返回 undefined

    function doNothing() {}
    console.log(doNothing()); // 输出: undefined
    
  • 函数的参数未传递:当函数调用时未传递某个参数,该参数值为 undefined

    function greet(name) {
      console.log(name); // 如果未传递参数,name 的值是 undefined
    }
    greet(); // 输出: undefined
    

3. nullundefined 的区别

特性 null undefined
定义 表示“有意的空值”或“无值” 表示“未定义”或“未赋值”
数据类型 "object"(历史遗留问题) "undefined"
变量声明后的默认值 不是默认值 未赋值变量的默认值
用法 开发者明确赋值为 null 通常由 JavaScript 引擎自动赋值
表示的语义 表示“空”或“无值”,但这是开发者主动设置的 表示“未定义”,通常是系统自动赋值的结果

4. nullundefined 的相等性比较

4.1 使用宽松相等(==

在宽松相等(==)比较中,nullundefined 被认为是相等的:

console.log(null == undefined); // 输出: true

4.2 使用严格相等(===

在严格相等(===)比较中,nullundefined 是不同的:

console.log(null === undefined); // 输出: false

原因是它们的类型不同:

  • null"object" 类型。
  • undefined"undefined" 类型。

5. 常见场景和区别

5.1 变量声明后的默认值

未赋值的变量会是 undefined,而不是 null

let value;
console.log(value); // 输出: undefined

如果开发者明确想表示“没有值”,通常会将变量设置为 null

let value = null;
console.log(value); // 输出: null

5.2 函数返回值

  • 函数没有显式返回值时,返回的是 undefined

    function doNothing() {}
    console.log(doNothing()); // 输出: undefined
    
  • 如果函数需要明确表示“没有结果”,可以返回 null

    function findUser(id) {
      if (id !== 1) return null; // 没有找到用户,返回 null
      return { id: 1, name: "Alice" };
    }
    console.log(findUser(2)); // 输出: null
    

5.3 对象属性

  • 访问对象中不存在的属性会返回 undefined

    const obj = {};
    console.log(obj.name); // 输出: undefined
    
  • 如果开发者需要明确表示某个属性“没有值”,可以将其设置为 null

    const obj = { name: null };
    console.log(obj.name); // 输出: null
    

5.4 JSON 序列化

  • null 会被序列化为 null
  • undefined 属性会被忽略。
const data = {
  a: null,
  b: undefined
};
console.log(JSON.stringify(data)); 
// 输出: {"a":null}

6. 如何选择使用 nullundefined

6.1 使用 null 的情况

  • 当你需要明确表示“无值”时。

  • 当你需要重置变量以释放资源或清空数据时。

    let user = { name: "Alice" };
    user = null; // 清空 user
    

6.2 使用 undefined 的情况

  • undefined 通常是系统默认的结果,开发者很少需要显式地设置一个变量为 undefined
  • 在函数参数未传递时,函数可以检测到参数是 undefined

7. 总结

  • null 表示“有意设置为空值”,这是开发者主动赋值的结果,代表“此处没有值,但值是明确的”。
  • undefined 表示“未定义”,通常是系统默认的结果,代表“此处缺失值,并且未被初始化”。

可以简单理解为:

  • null 是“有意地没有”,表示“空值”。
  • undefined 是“无意地没有”,表示“未定义”。