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

最近有點忙,公司有個新項目要儘快上線,因此工做時間很長,沒有太多的時間去學習和總結,因此博客也沒空更新了。可是充足的工做量讓本身以爲很充足,沉澱的知識也有了用武之地,還不錯。今天就寫寫這兩天忽然想到的一個小問題吧,感受不是很重要,瞭解一下就ok了javascript

時常見到void或者void(0)

在我剛接觸前端的時候,在那個前端尚未從蠻荒時代走出來的時候,不少時候方法和屬性都是直接寫在標籤上的,相似下面⬇️html

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

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

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

像上面這種寫法,我估計不少前端的小夥伴也都見過,而且可能知道這麼寫是爲了讓a標籤沒有做用,不會跳轉頁面,也不會跳轉錨點,可是爲何要這麼寫,我也是前幾天忽然想到的,就找了找資料看了一下。java

認識void

void運算符對給定的表達式進行求值,而後返回undefined;————《MDN web docs》node

理解一下上面的解釋能執行包含的代碼,而後再返回undefined;web

當即調用的函數表達式

void能夠完成以下的騷操做⬇️chrome

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

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

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

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

在使用當即執行的函數表達式時,能夠利用void運算符讓JavaScript引擎把一個function關鍵字識別成函數表達式而不是函數聲明(語句)。————《MDN web docs》segmentfault

就是說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都被咱們從新賦值了,咱們再來看看瀏覽器中的結果

好樣的,這樣看來瀏覽器是有本身的結界的,可是咱們若是不輸出全局的呢?

完蛋,結界被破了,這下咱們得出來一個結論
瀏覽器環境中的局部做用域中是能夠更改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:;的用法》

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

相關文章
相關標籤/搜索