JS 冷知識: 你所不知道的 void
在 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
這樣的作用。