恩,这是个问题。如果你有印象,void
甚至是js中的26个关键字之一,根据ECMA官方标准,它是一个一元操作符,它的唯一作用就是返回一个undefined
,不管这个操作符后面传的操作数是什么。
在标准里对void
的执行细节是这么说的:
- Let expr be the result of evaluating UnaryExpression.--》把表达式的值赋给expr;
- Call GetValue(expr).--》调用expr的内部函数获取它的值;
- Return undefined. --》返回undefined
这有点像那个很有意思的笑话:
客官你吃啥?
啊,我要一碗牛肉面,面给我多煮会少放点葱多放点辣肉给我放多一点汤给我多盛点。
哦,一碗牛肉面。
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
的时候,可以用这个操作符。通常有如下使用场景:
一、Javascript URIs
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
下次再说。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。