最近有點忙,公司有個新專案要儘快上線,所以工作時間很長,沒有太多的時間去學習和總結,所以部落格也沒空更新了。但是充足的工作量讓自己覺得很充足,沉澱的知識也有了用武之地,還不錯。今天就寫寫這兩天突然想到的一個小問題吧,感覺不是很重要,瞭解一下就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);
複製程式碼
這樣一行程式碼看看會執行成什麼樣
undefined
都被我們重新賦值了,我們再來看看瀏覽器中的結果
好樣的,這樣看來瀏覽器是有自己的結界的,但是我們如果不輸出全域性的呢?
完蛋,結界被破了,這下我們得出來一個結論
瀏覽器環境中的區域性作用域中是可以更改undefined
的值,而在node環境全域性和區域性都可以更改undefined
的值,究其原因,因為undefined
在JavaScript中既不是關鍵字也不是保留字,所以很容易被汙染
證據:
underscore中的使用
那undefined
的值這麼容易就被人改變,但像我們這種菜雞當然不會用嚴謹的方式去取的undefined
的值,但是想一些開源庫,力求嚴謹的態度,讓他們會使用void(0)
這種方法去獲取undefined
的值
void 0
去獲取undefined
的值
但是令我費解的是?,師出同門的Lodash卻沒有使用這種方法。。。。。為啥??
就這些吧
以上就是我目前對void
這個東西的理解了。。。也不知道理解到什麼程度。。尷尬
今天就先這樣吧,有人催我更新,不是我不想更,實在是沒有時間呢最近,中午午休的時間總結一下最近看的void
。幹活啦,公司這次的專案感覺會很牛逼。
參考連結
- 《MDN web docs》
- 《菜鳥教程》
- 《談談Javascript中的void操作符》
- 《(void 0)與undefined之間的小九九》
- 《為什麼用「void 0」代替「undefined」》
- 《javascript:void(0)和javascript:;的用法》
我是前端戰五渣,一個前端界的小學生。