在阅读一些框架源码时,发现都是用的 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 来判断是不是原始值。


huaguzheng
496 声望1 粉丝