谈谈Javascript中的void

简单版

void是一个一元操作符,根据MDN的说法

The void operator evaluates the given expression and then returns undefined.

void操作符会对给定表达式求值,然后返回undefined

也就是说无论表达式是什么,void都会返回一个undefined:

1
2
3
4
5
6
7
8
void 'a' // undefined
void 0 // undefined。 同void(0)
void false // undefined
void new Object() // undefined
void Number() // // undefined
void 1 + 1 // NaN,因为void 1返回undefined
void function re(){console.log('sa')}() // 打印'sa',返回undefined
. . .

那么有什么用呢?

第一个用途,用来代替undefined

与很多人以为的不一样,undefined实际上并不是js的保留字,尽管ES5中undefined已经变成了全局对象的一个只读属性,但在局部作用域中仍然可以被重写。

这就带来很多隐患。

为了解决这个问题我们可以使用void无论怎么样都返回undefined的特性,在需要undefined的时候使用void 0代替。

至于为什么用void 0而不用void(0)void 'hello,world!',主要是因为void 0短。这意味着尽管未来undefined会变成保留字,void 0也仍然会有用武之地,事实上很多压缩工具就是直接用void 0代替代码中的undefined。

第二个用途,用在Javascript URIs

在浏览器处理javascript: URI时,他会对URL那的代码求值然后用返回值替换页面上的内容,除非返回的是undefined。而void就可以帮我们返回undefined。

1
2
3
4
5
6
7
<a href="javascript:void(0);">
Click here to do nothing
</a>
<a href="javascript:void(document.body.style.backgroundColor='green');">
Click here for green background
</a>

不过现在javascript:已经不被推荐,虽然我并不知道为何不推荐= =

第三个用途,避免立即执行函数出错

通常我们写立即执行函数的时候都会加括号,例如这样:

1
2
3
(function add(){
// do something
})()

不过有的人为了省力气往往省略这个括号,省略本来并没有问题,不过这有时候会被js解释器错误的认为这是在函数声明。

通过在function前面加上void可以避免这种情况。

1
2
3
void function add(){
// do something
}()

事实上不只可以加void,也可以用!+等一元操作符替代。

复杂版

其实void在ECMAScript中的解释是这样的:

  1. Let expr be the result of evaluating
    UnaryExpression.
  2. Call GetValue(expr).
  3. Return undefined.

由于里面涉及了一些比较深入的js知识,我现在并不太清楚究竟做了什么。待日后更新。

Reference:

void关键字有个毛用

从用 void 0 代替 undefined 说起

谈谈Javascript中的void操作符

void operator–MDN