为何有的编程规范要求用 void 0 代替 undefined

Undefined

Undefined 类型表示未定义,它的类型只有一个值,就是 undefined。javascript

任何变量在被赋值前它的值都是 undefined,可是在 JavaScript 引擎中,undefined 是一个变量而非关键字。在旧的浏览器中,全局变量 undefined 能够被重写。前端

/**
 * IE8 浏览器
 */
var value;
console.log(value === undefined); //true
// 重写 undefined
undefined = 'hi';
console.log(value === undefined); //false

从上面的例子可知,在旧的浏览器下若是 undefined 被重写为非 undefined 值,那么它就没法用来正确检测一个变量是否被赋值。java

这个问题在 ECMAScript 5 中被修复了,在实现了 ECMAScript 5 规范的浏览器中运行如下代码。git

/**
 * Chrome 浏览器
 */ 
Object.getOwnPropertyDescriptor(window, undefined); //运行结果:{"writable":false,"enumerable":false,"configurable":false}

从上面的运行结果可知,全局变量 undefined 的 writable 属性是 false,也就是不可写。github

void

void 运算符对给定的表达式进行求值,会忽略计算结果并始终返回 undefined。编程

var value1 = 'hi';
console.log(value1); //"hi"

var value2 = void 'hi';
console.log(value2); //undefined

所以,咱们能够利用这一点准确地获取预期的 undefined 值。segmentfault

var value;
console.log(value === void 0); //true
console.log(value === void(0)); //true

最后

从上面的测试结果来看,有的编程规范要求使用 void 0 代替 undefined,主要缘由在于避免 undefined 值被重写带来的风险。现代浏览器中,全局变量 undefined 是不可写的,若是不考虑兼容旧的浏览器,那么这个问题就不用太过在乎。浏览器

扩展

许多 JavaScript 压缩工具,已经帮助咱们针对 undefined 的这个问题作出了处理。工具

/**
 * 源码
 */
var value;
console.log(value === undefined);
/**
 * 使用 uglify 压缩
 */
"use strict";var value;console.log(void 0===value);

参考文档

相关文章
相关标签/搜索