Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React

  • Vue

  • JavaScript文章

    • Map和WeakMap
    • Set和WeakSet
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • 几个高级的JS API
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
    • Navigator clipboard介绍使用
    • Javascript 语法错题集
    • ESM和CommonJS详解
    • ColorThief的介绍与使用
    • new命令原理
    • 扩展运算符
    • 遍历深层对象指定层级的属性
    • 一文弄懂typeof和instanceof
    • JS中可迭代的数据类型
    • 比较两个字符串的大小
    • requestIdleCallback
    • undefined和void
      • 核心概念解析
        • undefined 是什么?
        • void 运算符是什么?
      • 关键区别对比
      • 为什么需要 void 0?
        • 1. 历史原因:undefined 可被重写
        • 2. 作用域安全性
        • 3. 代码压缩优势
      • 现代 JavaScript 中的使用
        • ES5+ 环境下的变化
        • 最佳实践建议
      • 特殊应用场景
        • 1. 阻止链接跳转
        • 2. IIFE 中的安全 undefined
        • 3. 最小化副作用
      • 性能比较
      • 替代方案:安全访问 undefined
        • 1. 使用全局对象
        • 2. ES6 默认参数
      • 总结与最佳实践
    • axios取消http请求
  • 学习笔记

  • openlayers

  • threejs

  • MapboxGL

  • 工具

  • 源码合集

  • ECMAScript历年新特性

  • 前端
  • JavaScript文章
东流
2025-09-04
目录

undefined和void

# 前端中的 void 0 与 undefined 深度解析

在 JavaScript 中,void 0 和 undefined 都表示"未定义"的概念,但它们在使用场景、行为特性和最佳实践方面存在重要差异。本文将全面解析这两者的区别和应用场景。

# 核心概念解析

# undefined 是什么?

undefined 是 JavaScript 中的一个原始值,表示变量未被赋值或对象属性不存在。它是全局对象的一个属性(在浏览器中是 window.undefined)。

let unassigned;
console.log(unassigned); // undefined

const obj = {};
console.log(obj.nonExistentProperty); // undefined
1
2
3
4
5

# void 运算符是什么?

void 是一个运算符,它计算给定的表达式,然后返回 undefined。语法为 void expression。

console.log(void 0); // undefined
console.log(void "hello"); // undefined
console.log(void (2 + 2)); // undefined
1
2
3

# 关键区别对比

特性 undefined void 0
类型 原始值 运算符
可重写性 ES5前可被重写 不可重写
作用域安全性 局部作用域可能被覆盖 始终安全
代码压缩 9个字符 6个字符
使用场景 常规开发 库开发、安全关键代码
返回值 值本身 总是返回 undefined

# 为什么需要 void 0?

# 1. 历史原因:undefined 可被重写

在 ES5 之前(2009年前),undefined 可以被重新赋值:

// ES3 环境中(已过时但需了解)
undefined = "now I'm defined";
console.log(undefined); // "now I'm defined"
1
2
3

void 0 提供了一种始终获取真正 undefined 值的安全方式:

console.log(void 0); // undefined (始终安全)
1

# 2. 作用域安全性

即使在现代 JavaScript 中,局部作用域中仍可声明名为 undefined 的变量:

(function() {
  const undefined = "defined";
  console.log(undefined); // "defined"
  console.log(void 0); // undefined
})();
1
2
3
4
5

# 3. 代码压缩优势

在库开发中,使用 void 0 可以节省空间:

// 原始代码
if (value === undefined) { /* ... */ }

// 压缩后
if (a===void 0){/* ... */} // 更短
1
2
3
4
5

# 现代 JavaScript 中的使用

# ES5+ 环境下的变化

从 ES5 开始,全局 undefined 变为只读:

// 现代浏览器中
undefined = "new value"; 
console.log(undefined); // 仍然输出 undefined(严格模式下报错)
1
2
3

但在严格模式下,尝试修改 undefined 会报错:

"use strict";
undefined = "new value"; // TypeError: Cannot assign to read only property
1
2

# 最佳实践建议

  1. 常规开发:使用 undefined 更直观

    function greet(name = "Guest") {
      if (name === undefined) {
        console.log("Hello, Guest!");
      } else {
        console.log(`Hello, ${name}!`);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. 库/框架开发:使用 void 0 确保绝对安全

    // jQuery 源码示例
    jQuery.extend = function() {
      var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;
      
      // 使用 void 0 检查 undefined
      if (typeof target === "boolean") {
        deep = target;
        target = arguments[i] || {};
        i++;
      }
      
      // ...
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  3. 立即返回 undefined

    // 在箭头函数中返回 undefined
    const noop = () => void 0;
    
    // 替代方案
    const noopAlt = () => undefined;
    
    1
    2
    3
    4
    5

# 特殊应用场景

# 1. 阻止链接跳转

在 HTML 中,void 0 常用于阻止默认行为:

<a href="javascript:void(0)" onclick="doSomething()">
  点击不会跳转
</a>
1
2
3

# 2. IIFE 中的安全 undefined

(function(undefined) {
  // 这里 undefined 是安全的
  const isUndefined = value => value === undefined;
  
  console.log(isUndefined()); // true
})(void 0);
1
2
3
4
5
6

# 3. 最小化副作用

// 只执行函数,忽略返回值
void fetchDataAndUpdateUI();

// 等同于
fetchDataAndUpdateUI();
undefined; // 但 void 更明确表示忽略返回值
1
2
3
4
5
6

# 性能比较

在现代 JavaScript 引擎中,undefined 和 void 0 的性能差异可以忽略不计:

// 性能测试
const iterations = 1e8;

console.time('undefined');
for (let i = 0; i < iterations; i++) {
  const test = undefined;
}
console.timeEnd('undefined');

console.time('void 0');
for (let i = 0; i < iterations; i++) {
  const test = void 0;
}
console.timeEnd('void 0');
1
2
3
4
5
6
7
8
9
10
11
12
13
14

典型结果(Chrome 115):

  • undefined: ~50ms
  • void 0: ~55ms

差异微小,不应作为选择依据。

# 替代方案:安全访问 undefined

# 1. 使用全局对象

// 浏览器环境
const safeUndefined = window.undefined;

// 通用方法
const getSafeUndefined = () => {
  const _undefined = void 0;
  return _undefined;
};
1
2
3
4
5
6
7
8

# 2. ES6 默认参数

function isUndefined(value = void 0) {
  return value === void 0;
}
1
2
3

# 总结与最佳实践

  1. 现代开发(ES5+):

    • 优先使用 undefined,更直观易读
    • 在严格模式下,undefined 是安全的
  2. 库/框架开发:

    • 使用 void 0 确保绝对兼容性
    • 特别支持旧浏览器时必要
  3. 特殊场景:

    • 需要绝对安全时用 void 0
    • 需要最小化代码时用 void 0
    • HTML 中阻止默认行为用 javascript:void(0)
  4. 避免:

    • 不要使用 void 0 代替 undefined 作为默认参数值
    • 不要在现代项目中过度使用 void 0 降低可读性
// 现代最佳实践示例
function modernExample(param) {
  // 检查 undefined
  if (param === undefined) {
    console.log("参数未提供");
  }
  
  // 安全访问可能被覆盖的环境
  const safeCheck = (function(undefined) {
    return value => value === undefined;
  })(void 0);
  
  console.log(safeCheck()); // true
}

// 库开发示例
function libraryExample(value) {
  // 使用 void 0 确保安全
  if (value === void 0) {
    return defaultValue;
  }
  return process(value);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

理解 void 0 和 undefined 的区别有助于编写更健壮的 JavaScript 代码,特别是在开发需要广泛兼容性的库和框架时。

编辑 (opens new window)
上次更新: 2025/09/05, 09:36:06
requestIdleCallback
axios取消http请求

← requestIdleCallback axios取消http请求→

最近更新
01
directive自定义指令实现原理
09-12
02
scheduler调度器
09-10
03
watch和watcherEffect源码解析
09-09
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式