在 JavaScript 裡, void 運算子可以說是存在感最薄弱的一個了,這個運算子只有一個功能,就是接收任意的運算式或值,然後回傳 undefined。 (你沒看錯,就是 undefined)

用法與 typeof 一樣,可以在後面加上小括號 () 或是直接加上某個值:

void 0;   // undefined
void(0);  // undefined

毫無反應,就是回傳 undefined

而你可能在某些地方看過 void(0) 這樣的程式碼,尤其是在 <a> 標籤的 href 屬性: <a href="javascript:void(0)">...</a>

那麼這樣一個神奇的 void 運算子到底是用來做什麼的呢?

根據 ECMAScript 262 的規範中提到:

The void Operator

The production UnaryExpression : void UnaryExpression is evaluated as follows:

  • Let expr be the result of evaluating UnaryExpression.
  • Call GetValue(expr).
  • Return undefined.

NOTE: GetValue must be called even though its value is not used because it may have observable side-effects.

雖然無論 void 後面的值是什麼,它都會回傳 undefined 的結果,但是有個需要特別注意的地方是,這個 void 後面接的運算式是「會被執行的」(有沒有加上括號無所謂)。

// console 主控台會印出 "HI",然後回傳 undefined
void (console.log('HI!'));

而在 href 裡面加上 javascript:void(0) 代表著這是一個無目標的死連結。

當然自從我們有了 HTML / JS 分離的概念後,多數開發者會採用在 click event 裡面加上 e.preventDefault() 的方式來阻擋預設事件。

但是早期 (指 IE9 以前) 瀏覽器的事件綁定就至少有 W3C DOM 標準的 element.addEventListener 與 IE 獨有的 element.attachEvent 要處理, 在過去,與其要自己特別處理不同事件的阻擋,還不如直接下 <a href="javascript:void(0)">...</a> 來得快速,而且還可以再下 onclick="..." 來處理後續對應的行為。

不過此時此刻多數瀏覽器都已遵循 DOM 標準,現在不太需要這樣處理了,只是我們多少還會看到 href="javascript:void(0)" 這樣的做法。

另外,要是 void 後面再加上一個 IIFE,即使這個 function 是有名字的:

void function saySomething (msg) {
  console.log(msg);
} ('Hello');

因為 void 後面的指令是會執行的,所以此時 console 會直接印出 "Hello" 的字樣。

若你再嘗試去呼叫 saySomething 這個函式:

// console.log 會立即印出 "Hello"
void function saySomething (msg) {
  console.log(msg);
} ('Hello');

// 則會出現 Uncaught ReferenceError: saySomething is not defined 的錯誤訊息
saySomething('Hi');

像這樣,雖然 void 的使用情境不多,但有些開發者會習慣在此類一次性呼叫的 IIFE 前面加上 void 來增加程式碼的可讀性。


最後再分享一個有趣的事,如果你曾使用過 LiveScript 開發,你可能會看過編譯出來的 JavaScript 程式有很多 void 8,像這樣:

x = if truthy then success!

上面這段程式編譯後會得到:

var x;
x = truthy ? success() : void 8;

根據前面的說明我們都知道 void 8 最後會得到 undefined 的結果,而這個 void 8 有沒有什麼特別用意呢?

其實沒有,根據 LiveScript 的核心 coco 裡的解釋:

void 8 - the number 8 was chosen because it is a Chinese lucky number.

使用 8 單純只是它在中文代表是個幸運的數字 (音近似「發」) ,換成其他數字都可以,重點只是取它回傳 undefined 這樣的作用。