某天,在看某位同窗的js代碼,代碼中發現了一個奇怪的東西 void 0,雖然第一眼看不懂這是什麼東西,可是根據上下文,這裏應該是想判斷是否等於undefined,爲何要這樣寫的,有什麼淵源嗎?順便就把undefined和null都拿出來複習了一下.javascript
undefined和null是js中類型七種數據類型,這兩種數據的區別是java
null是有一些奇怪的地方,例如常見的面試題程序員
typeof null 爲何是object?面試
這道題目在我一開始學習js的時候就接觸過,說是js設計的一個bug啦,只是由於舊代碼太多,怕改正過來會形成影響,因此一直保持,也有的說這是一個空指針,空對象,因此爲object.可是我總以爲這樣說服力不夠,因而我上網翻了一些資料瀏覽器
在 javascript 的最第一版本中,使用的 32 位系統,而且底層都表示爲2進制,爲了性能考慮使用低位存儲了變量的類型信息:bash
000:對象函數
1:整數性能
010:浮點數學習
100:字符串測試
110:布爾
所有爲0: null
因此typeof就是利用這一機制去判斷的,因此null所有爲0就複合了對象的000,因此被判斷爲object
而且還有個注意點
null == undefined //true null和undefined用==比較結果是true,而且沒有發生隱式轉換,就是true
複製代碼
接下來就是undefined了,這個設計感受也有個很是大的bug,那麼重要的東西,居然不是一個關鍵字,居然是一個變量.一個變量意味着什麼,你能夠隨意更改它啊!!
因此有的程序員就會利用void 0去代替undefined,鬼知道原來的undefined會不會被某個陰險小人替換了.
根據ECMAScript,void後面接什麼都是undefined,也有的說void 0 是從其餘語言帶過來的習慣,是一種老司機的寫法,因此下次咱們要用到undefined的時候就要void 0代替,這樣比較顯得老司機
這裏我本身測試了一下
var undefined = 2;
console.log(undefined); //undefined
複製代碼
結果是undefined,也就是在新版的谷歌瀏覽器裏面的全局做用域下面是沒法更改undefined的
//此次改用const
const undefined = 2; //Identifier 'undefined' has already been declared
console.log(undefined);
複製代碼
用const則會報錯,已經declared了,let也一樣
var undefined = 2;
console.log(undefined); //undefined
複製代碼
這樣的結果仍是undefined,因此在ie11的全局做用域下面也不能替換
var undefined = 2;
console.log(undefined); //2
複製代碼
居然改變了,ie8的全局做用域下是能夠改變undefined的
這樣看來好像也沒什麼用是否是?ie8不少公司都不用去兼容了,慢着
(function () {
var undefined = 2
console.log(undefined); //2
})()
複製代碼
發現這樣就改變了undefined
(function () {
const undefined = 2
console.log(undefined); //2
})()
複製代碼
const一樣可行,而且在ie的11,10,9,8幾個版本中,無一例外的,undefined都被覆蓋了
這時候想到,在全局做用域下,全局變量會變成window上面的一個屬性,這時候咱們查查看這個屬性有什麼特別不就知道緣由了
console.log(Object.getOwnPropertyDescriptor(window, undefined)); //{value: undefined, writable: false, enumerable: false, configurable: false}
複製代碼
這時候拿到數據屬性能夠看到,不可重寫,不可枚舉,不可改變特徵值或者被刪除,因此在全局做用域下面是不能夠被重寫的.
那ie8呢?爲何能夠?
console.log(Object.getOwnPropertyDescriptor(window, undefined)); //{configurable: false, enumerable: false, value: undefined, writable: true}
複製代碼
ie8一樣,不可枚舉,不可刪除或修改特徵值,可是!!能夠被重寫!!因此ie8的全局做用域上面是能夠被重寫的!!
結論:雖然undefined在如今主流的絕大部分瀏覽器的全局做用域上面都是不能更改了,可是在函數做用域或者塊級做用域下面仍是能被重寫的,固然絕大部分人應該都不會去幹這種傻事,可是仍是用viod 0吧,這樣能夠以防萬一,同時也更像一個老司機的代碼啊