前端戰五渣學JavaScript——void 運算子

前端戰五渣發表於2019-04-12

最近有點忙,公司有個新專案要儘快上線,所以工作時間很長,沒有太多的時間去學習和總結,所以部落格也沒空更新了。但是充足的工作量讓自己覺得很充足,沉澱的知識也有了用武之地,還不錯。今天就寫寫這兩天突然想到的一個小問題吧,感覺不是很重要,瞭解一下就ok了

時常見到void或者void(0)

在我剛接觸前端的時候,在那個前端還沒有從蠻荒時代走出來的時候,很多時候方法和屬性都是直接寫在標籤上的,類似下面⬇️

  <div onclick="aaa"></div>
  <p onmouseenter="bbb"></p>
  <a href="https://www.alibaba.com/"></a>
複製程式碼

絕大多數的時候我發現很多a標籤的href寫的不是個地址,或者#等各種錨點,而是⬇️

  <a href="javascript:void(0);"></a>
複製程式碼

像上面這種寫法,我估計很多前端的小夥伴也都見過,並且可能知道這麼寫是為了讓a標籤沒有作用,不會跳轉頁面,也不會跳轉錨點,但是為什麼要這麼寫,我也是前幾天突然想到的,就找了找資料看了一下。

認識void

void運算子對給定的表示式進行求值,然後返回undefined;————《MDN web docs》

理解一下上面的解釋能執行包含的程式碼,然後再返回undefined;

立即呼叫的函式表示式

void可以完成如下的騷操作⬇️

(function () {
  console.log(123)
})(); // 123

void function () {
  console.log(321)
}(); // 321

function b() {
  console.log('error')
}(); // 報錯
複製程式碼

第一種方法我們很清楚是一個自執行的函式,而第二種方法我們在一個方法前面寫上void並且在函式末尾寫上執行的括號,這個函式也變成了一個自執行的函式,而三種的方法只是為了證實我們不寫void的時候,這種寫法是不會執行,並且報錯的。

在使用立即執行的函式表示式時,可以利用void運算子讓JavaScript引擎把一個function關鍵字識別成函式表示式而不是函式宣告(語句)。————《MDN web docs》

就是說void會識別後面為自執行的函式,而不是僅僅宣告一個函式

函式表示式和宣告函式不明白的可以檢視函式表示式

javascript URIs & javscript:void(0);

我們首先要知道,我們開頭提到的在a標籤的href屬性上寫javascript:URI 的時候,它會執行URI中的程式碼,然後用返回的值替換頁面內容,除非返回的值是undefined,而void()恰巧可以返回undefined
我們先來看看javascript URIs是如何執行程式碼的。

<a href="javascript: alert('我被執行了');">彈出彈框</a> <!-- 點選頁面我們可以看見alert彈框被彈出來了 -->
複製程式碼

上面的程式碼我們可以看出來javascript URIs確實可以再href中被執行。
下面我們來看加入void運算子的結果⬇️

<!-- 以下操作請用火狐瀏覽器操作,chrome不會有變化,所以可以看出有些方法至今各大瀏覽器的解析策略還是不一樣的 -->
<a href="javascript: 0;">替換頁面為0</a> <!-- 這個a標籤在頁面中點選以後,頁面會被替換成0 -->
<a href="javascript: void(0);">替換頁面為0</a> <!-- 而這個a標籤在頁面中點選以後,頁面沒有任何反應,因為void(0)返回的是0,所以不做處理 -->
複製程式碼

上面的程式碼我們能發現加入了void()以後,頁面無動於衷,也沒有被0替換。

href="#"href="javascript: void(0)"

經過上面的章節我們已經知道了href="javascript: void(0)"是讓點選a標籤沒有任何效果,但是我們前端的小夥伴有時候為了阻止這種情況發生,會href="#"這麼寫。這麼寫的意思是什麼呢?執行的時候會預設執行href="#top",頁面的滾動條會滾動到頁面的最上面,所以,這自然不是我們想要的。(而且位址列的地址後面會跟上一個井號,多難看啊)

JavaScript中使用void

既然我們知道了void的作用,那在實際的JS程式設計中有什麼作用呢。來,上程式碼⬇️

let undefined = '我是全域性的undefined,我被人修改了';

function print() {
  let undefined = '我是區域性的undefined,我被人修改了';
  console.log(undefined)
}

print();
console.log(undefined);
複製程式碼

這樣一行程式碼看看會執行成什麼樣

node中執行
這是在node中執行的,我們可以看出來不管是全域性還是區域性的undefined都被我們重新賦值了,我們再來看看瀏覽器中的結果

前端戰五渣學JavaScript——void 運算子
好樣的,這樣看來瀏覽器是有自己的結界的,但是我們如果不輸出全域性的呢?

前端戰五渣學JavaScript——void 運算子

完蛋,結界被破了,這下我們得出來一個結論
瀏覽器環境中的區域性作用域中是可以更改undefined的值,而在node環境全域性和區域性都可以更改undefined的值,究其原因,因為undefined在JavaScript中既不是關鍵字也不是保留字,所以很容易被汙染 證據:

《JavaScript高階程式設計》

《JavaScript高階程式設計》
以上都是摘自《JavaScript高階程式設計》

underscore中的使用

undefined的值這麼容易就被人改變,但像我們這種菜雞當然不會用嚴謹的方式去取的undefined的值,但是想一些開源庫,力求嚴謹的態度,讓他們會使用void(0)這種方法去獲取undefined的值

underscore中的實踐
上面只是我擷取的underscore中的部分程式碼,但從中我們就可以發現,他們確實是使用void 0去獲取undefined的值

但是令我費解的是?,師出同門的Lodash卻沒有使用這種方法。。。。。為啥??

就這些吧

以上就是我目前對void這個東西的理解了。。。也不知道理解到什麼程度。。尷尬

今天就先這樣吧,有人催我更新,不是我不想更,實在是沒有時間呢最近,中午午休的時間總結一下最近看的void。幹活啦,公司這次的專案感覺會很牛逼。

參考連結

  1. 《MDN web docs》
  2. 《菜鳥教程》
  3. 《談談Javascript中的void操作符》
  4. 《(void 0)與undefined之間的小九九》
  5. 《為什麼用「void 0」代替「undefined」》
  6. 《javascript:void(0)和javascript:;的用法》

我是前端戰五渣,一個前端界的小學生。

相關文章