恩,这是个问题。如果你有印象, void
甚至是js中的26个关键字之一,根据 ECMA官方标准 ,它是一个一元操作符,它的唯一作用就是返回一个 undefined
,不管这个操作符后面传的操作数是什么。
在标准里对 void
的执行细节是这么说的:
这有点像那个很有意思的笑话:
客官你吃啥?
啊,我要一碗牛肉面,面给我多煮会少放点葱多放点辣肉给我放多一点汤给我多盛点。
哦,一碗牛肉面。
void
可以像下面这样使用:
javascript
void 0; void "you are useless?"; void false; void []; void /(useless)/ig; void function(){ console.log("you are so useless?"); } //... always return undefined
后面可以是任何表达式,返回的永远是 undefined
!很明显,在你想获得 undefined
的时候,可以用这个操作符。通常有如下使用场景:
html
<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>
这是 MDN文档 中给出的例子,我之前看到不少远古时代的网页应用这样的写法,就是直接在 a
标签的 href
属性里写js代码,比如 <a href="javascript:;">link</a>
,这样写跟 <a href="#">link</a>
的区别是后者在点击的时候页面会跳到最顶部去,如果这不是你要的效果一定要注意;在 href
里写 javascript:void(0);
则可以避免上述问题。
不过现在这样写 javascript:
是不提倡的。
你们一定已经看到过闭包的这种写法:
javascript
!function fn(){ console.log("I will show immediately.") }()
上述这段代码中的 !
可以换成其他操作符,比如 +
、 -
、 ~
,加上这些前缀的作用是避免js解析器讲函数体解析为函数声明。
解析器在遇到代码 function fn(){ /*...*/}
时会把这解析成函数声明,在函数声明后面再跟着一对括号会产生语法错误,前面加上一个操作符,解析器就会把这段代码当成函数表达式,从而可以顺利执行。
在前面这个场景中,这个操作符也可以用 void
,效果与上述代码一致。
javascript
void function fn(){ console.log("I will show immediately.") }()
那么问题是,为什么不直接使用 undefined
这个值的字面量形式呢?
我在 stackoverflow 上找到一个解释:
因为 undefined
既不是保留字,也不是关键字,它可以作为变量标识符赋值,所以你手写出来的 undefined
是 有可能被覆盖 的!比如:
javascript
var undefined="oops"; alert(undefined);
上述代码在一些原始社会的浏览器中会成功弹出 oops
,说到原始社会的浏览器,我们来试试IE吧。经过测试,这段代码在IE9以下的浏览器中真的会弹出 oops
! oops! 你也可以试试。
不过,在现代浏览器中,已经不能这么做了,仍然可以给 undefined
赋值,但这个是无效的。试试跟 undefined
很类似的 null
,给它赋值就会报错。
所以,当我们要获得真正的 undefined
值的时候,用 void
操作符吧。 void
后面可以是任何操作数(注意:如果后面没有操作数也会报错的),那使用时用什么呢?良心推荐还是写 void 0
吧,毕竟这是最简短的。
关于数组中的 undefined
,还有一些很奇怪的地方,比如,如何区分下面这两个数组中的各项是不是相同:
javascript
var arr1=[1,2,undefined,4]; var arr2=[1,2,,4]; arr1[2]===arr2[2]; //true
下次再说。