JS中的null和undefined,undefined爲啥用void 0代替?

原由

  某天,在看某位同窗的js代碼,代碼中發現了一個奇怪的東西 void 0,雖然第一眼看不懂這是什麼東西,可是根據上下文,這裏應該是想判斷是否等於undefined,爲何要這樣寫的,有什麼淵源嗎?順便就把undefined和null都拿出來複習了一下.javascript

介紹

  undefined和null是js中類型七種數據類型,這兩種數據的區別是java

  • undefined是聲明瞭未定義
  • null是一個空指針,除非定義爲null,不然不會出現null

null

   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

  接下來就是undefined了,這個設計感受也有個很是大的bug,那麼重要的東西,居然不是一個關鍵字,居然是一個變量.一個變量意味着什麼,你能夠隨意更改它啊!!

  因此有的程序員就會利用void 0去代替undefined,鬼知道原來的undefined會不會被某個陰險小人替換了.

那麼void 0究竟是怎麼來的?

根據ECMAScript,void後面接什麼都是undefined,也有的說void 0 是從其餘語言帶過來的習慣,是一種老司機的寫法,因此下次咱們要用到undefined的時候就要void 0代替,這樣比較顯得老司機

undefined什麼狀況下會被替換?

這裏我本身測試了一下

  • 在谷歌瀏覽器69.0.3497.100版本下
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也一樣


  • 那就試試ie瀏覽器吧(IE11)
var undefined = 2;
    console.log(undefined); //undefined 
複製代碼

這樣的結果仍是undefined,因此在ie11的全局做用域下面也不能替換

  • 直到ie8版本的瀏覽器發生了變化
var undefined = 2;
    console.log(undefined); //2
複製代碼

居然改變了,ie8的全局做用域下是能夠改變undefined的

這樣看來好像也沒什麼用是否是?ie8不少公司都不用去兼容了,慢着

  • 在谷歌瀏覽器69.0.3497.100版本下,咱們試試在函數做用域下
(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吧,這樣能夠以防萬一,同時也更像一個老司機的代碼啊

相關文章
相關標籤/搜索