在阅读源码中,经常会看到 const XX=void0这里的 void 0其实就是 undefined,void 运算符总会返回一个 undefined 的结果。
那么,为什么要用 void 0 代替 undefined 呢?
总结:
undefined是一个「全局对象(如window)」中的一个「属性」, 在古老版本的浏览器里,它是可以被修改的undefined不是JavaScript的保留字(这点连百度和文心一言回答的都不对),因此它是可以被作为变量标识符而使用的。undefined在全局作用域中不重新赋值,但是在函数作用域中可以重新赋值,但是非常不建议这么做。<script>function demo(){let undefined="undefined1";console.log(undefined);}demo()</script>void expression它将会对表达式进行求值,然后返回undefined的「原始值」。void 0总是返回原始值undefined,无论全局属性undefined是否被改写,它都能确保其值是undefined(原始值)
下面是详细介绍:
一、void 运算符
语法非常简单:
void expression
它将会对表达式进行求值,然后返回 undefined 的「原始值」。那么,void 0 不就是得到 undefined 最简单的写法嘛!(请注意,写法上 void 0 相当于 void(0))。
我们知道,立即函数执行表达式(IIFE)要非常多的写法,使用 void 关键字也是可以的,比如:
void (function () {// some statements
})()// 相当于
void function () { /* some statements */ }()
另外,你应该看过以下类似的写法:
<a href="javascript:0;">Link</a>
我们知道 javascript: 是 JavaScript 中的伪协议,表示将会使用 JS 解析器执行其后的所有语句,若其最后一个JavaScript 语句返回值不为 undefined,那么其返回值将会替换为页面内容。
就以上 HTML 标签,在不同浏览器下点击,会有不同的结果。其中 Chrome、Safari 中点击无任何反馈,而 Firefox 中页面内容将会被替换为 0。
为了解决以上差异表现,通常的做法就是使用 void 关键字,比如:
<a href="javascript:void(0);">Link</a>
这也是处理 <a> 标签默认行为的方式之一。
这种伪协议除了在事件处理程序中使用,也可在浏览器地址栏、书签地址中使用。
除此之外,还有一种常用的用法:当箭头函数中只有一行语句,且不需要返回值时,则可以:
element.onclick = () => void doSomething()
二、undefined
你有可能不知道,我们天天写的 undefined,它其实是一个「全局对象」中的一个「属性」。
除了
undefined之外,类似的还有NaN、Infinity、globalThis也是全局对象的属性。它们的属性描述对象都是:不可写、不可枚举、不可配置(详看 ECMAScript 19.1 Value Properties of the Global Object)。
{[[writable]]: false,[[enumerable]]: false[[configurable]]: false
}
当然,这个在 ES5 之前是可以被改写的,下面可以对比一下:

还有,需要特别注意的是:
undefined并不是 ECMAScript 标准中的一个保留字,因此它是可以被作为变量标识符而使用的(但项目中千万别这么用),就行window一样。
在 ECMAScript 标准中,保留字有以下这些(详见 12.6.2 Keywords and Reserved Words):
undefined不是JavaScript的关键字和保留字,在全局作用域中不重新赋值,但是在函数作用域中可以重新赋值,但是不建议这么做,不建议将undefined作为变量、对象、函数等名称使用,在全局作用域中,undefined不可以重新赋值,即使重新赋值了,但是无效,在全局中输出的依然是undefined
<script>window.undefined = 1;console.log(window.undefined);//undefined</script>
但是在局部作用域中,可以将undefined作为变量名重新赋值,但是不建议这么做。
<script>function demo(){let undefined="undefined1";console.log(undefined);}demo()</script>
三、用 void 0 代替 undefined?
void 0 总是返回原始值 undefined,无论全局属性 undefined 是否被改写,它都能确保其值是 undefined(原始值)。
比如著名的工具库 underscore 大量使用了 void 0 来代替 undefined,再者 UglifyJS、Terser 等代码压缩工具也会将 undefined 转换为 void 0,这样可以节省一些字节:
但我们在编写代码的时候,直接使用 undefined 也是没有太大问题的,注意下前面提到的一些点就好了,其余的就交由工具来处理即可。