在阅读一些框架源码时,发现都是用的 void 0 代替 undefined,简单的 Google 了一下:
void 运算符
void 运算符 对给定的表达式进行求值,然后返回 undefined。
void 0; // undefined
void ('0'); // undefined
void "hello world"; // undefined
void function (){return 'foo'}() // undefined
undefined
我们经常会写如下判断
if (foo === undefined) {
foo = 'foo'
}
严格上来说这样的代码是不安全的,我们默认假设了 undefined 的值没有改动过。因为 undefined 不是 JavaScript 的保留字,只是全局变量上的一个属性,属性值是原始值 undefined。在 ECMAScript 5 之前,给 window.undefined 赋值会覆盖该属性。从 ECMAScript 5 开始undefined 是一个不能被配置(non-configurable),不能被重写(non-writable)的属性。
Object.getOwnPropertyDescriptor(window, 'undefined');
/* {
value: undefined,
writable: false,
enumerable: false,
configurable: false
} */
但是由于 undefined 不是保留字,依然可以在局部作用域中声明一个 undefined 的变量,并改变它的值。
function foo () {
let undefined = 'hello world';
return function (v) {
return v === undefined;
}
}
let isUndefined = foo();
let bar;
isUndefined(bar); // false
isUndefined(undefined); // false
isUndefined('hello world'); // true
安全的写法
一种是可以用 typeof,对于原始值 undefined , typeof 始终返回字符串 'undefined'
function foo () {
let undefined = 'hello world';
return function (v) {
return typeof v === 'undefined';
}
}
let isUndefined = foo();
let bar;
isUndefined(bar); // true
isUndefined(undefined); // true
isUndefined('hello world'); // false
另外一种就是 void 运算符,void 运算符始终返回原始值 undefined
function foo () {
let undefined = 'hello world';
return function (v) {
return v === void 0;
}
}
let isUndefined = foo();
let bar;
isUndefined(bar); // true
isUndefined(undefined); // true
isUndefined('hello world'); // false
当然,与 void 'hello world' 比较也是可以的,但是 void 0 字符数更短,写起来比 typeof 方便。因为框架代码不知道自己的执行上下文,也就不能假定 undefined 标识有没有被重新赋值过,所以用 void 0 来判断是不是原始值。