恩,這是個問題。若是你有印象,void
甚至是js中的26個關鍵字之一,根據ECMA官方標準,它是一個一元操做符,它的惟一做用就是返回一個undefined
,無論這個操做符後面傳的操做數是什麼。
在標準裏對void
的執行細節是這麼說的:javascript
- Let expr be the result of evaluating UnaryExpression.--》把表達式的值賦給expr;
- Call GetValue(expr).--》調用expr的內部函數獲取它的值;
- Return undefined. --》返回undefined
這有點像那個頗有意思的笑話:html
客官你吃啥?
啊,我要一碗牛肉麪,面給我多煮會少放點蔥多放點辣肉給我放多一點湯給我多盛點。
哦,一碗牛肉麪。java
void
能夠像下面這樣使用:數組
javascriptvoid 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:
是不提倡的。less
大家必定已經看到過閉包的這種寫法:函數
javascript!function fn(){ console.log("I will show immediately.") }()
上述這段代碼中的!
能夠換成其餘操做符,好比+
、-
、~
,加上這些前綴的做用是避免js解析器講函數體解析爲函數聲明。oop
解析器在遇到代碼
function fn(){ /*...*/}
時會把這解析成函數聲明,在函數聲明後面再跟着一對括號會產生語法錯誤,前面加上一個操做符,解析器就會把這段代碼當成函數表達式,從而能夠順利執行。測試
在前面這個場景中,這個操做符也能夠用void
,效果與上述代碼一致。
javascriptvoid function fn(){ console.log("I will show immediately.") }()
那麼問題是,爲何不直接使用undefined
這個值的字面量形式呢?
我在stackoverflow上找到一個解釋:
由於undefined
既不是保留字,也不是關鍵字,它能夠做爲變量標識符賦值,因此你手寫出來的undefined
是有可能被覆蓋的!好比:
javascriptvar undefined="oops"; alert(undefined);
上述代碼在一些原始社會的瀏覽器中會成功彈出oops
,說到原始社會的瀏覽器,咱們來試試IE吧。通過測試,這段代碼在IE9如下的瀏覽器中真的會彈出oops
! oops! 你也能夠試試。
不過,在現代瀏覽器中,已經不能這麼作了,仍然能夠給undefined
賦值,但這個是無效的。試試跟undefined
很相似的null
,給它賦值就會報錯。
因此,當咱們要得到真正的undefined
值的時候,用void
操做符吧。void
後面能夠是任何操做數(注意:若是後面沒有操做數也會報錯的),那使用時用什麼呢?良心推薦仍是寫void 0
吧,畢竟這是最簡短的。
關於數組中的undefined
,還有一些很奇怪的地方,好比,如何區分下面這兩個數組中的各項是否是相同:
javascriptvar arr1=[1,2,undefined,4]; var arr2=[1,2,,4]; arr1[2]===arr2[2]; //true
下次再說。