1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        深入探究 null 和 undefined 區(qū)別

        共 4090字,需瀏覽 9分鐘

         ·

        2022-02-19 02:03


        點(diǎn)擊上方?前端陽光,關(guān)注公眾號

        回復(fù)加群,加入技術(shù)交流群交流群


        前言

        該文章用了我?兩天?的時(shí)間來查各類資料,我盡可能的保證內(nèi)容的?準(zhǔn)確性?。
        如果你對任何內(nèi)容有?疑惑?或者?不同的見解?,歡迎在評論區(qū)友善留言。

        如果你是前端新人 ,看到?表現(xiàn)形式?這一章節(jié)就足夠。
        剩下的請收藏起來,待到以后想要更深入的了解,再繼續(xù)閱讀。

        簡單區(qū)分

        總的來說?null?和?undefined?都代表空,主要區(qū)別在于?undefined?表示尚未初始化的變量的值,而?null?表示該變量有意缺少對象指向。

        • undefined
          • 這個(gè)變量從根本上就沒有定義
          • 隱藏式 空值
        • null
          • 這個(gè)值雖然定義了,但它并未指向任何內(nèi)存中的對象
          • 聲明式 空值

        MDN 中給出的定義

        null

        值?null?是一個(gè)字面量,不像?undefined?,它不是全局對象的一個(gè)屬性。null?是表示缺少的標(biāo)識,指示變量未指向任何對象。把?null?作為尚未創(chuàng)建的對象,也許更好理解。在 API 中,null?常在返回類型應(yīng)是一個(gè)對象,但沒有關(guān)聯(lián)的值的地方使用。

        undefined

        undefined?是?全局對象?的一個(gè)屬性。也就是說,它是全局作用域的一個(gè)變量。undefined?的最初值就是原始數(shù)據(jù)類型?undefined?。

        一張神奇的圖片

        接下來我們看一張比較經(jīng)典的圖片,該圖來自 stackoverflow 的回答,本人沒有找到準(zhǔn)確的出處。

        表現(xiàn)形式

        在更深入理解?null?和?undefined?的區(qū)別前,我們首先要知道?null?和?undefined?在?JS?中有什么不同的表現(xiàn)形式,用以方便我們更好的理解?null?和?undefined?的區(qū)別。

        typeof

        typeof?null??//?'object'
        typeof?undefined??//?'undefined'
        復(fù)制代碼

        Object.prototype.toString.call

        typeof?null??//?'[object?Null]'
        typeof?undefined??//?'[object?Undefined]'
        復(fù)制代碼

        == 與 ===

        null?==?undefined??//?true
        null?===?undefined??//?false
        !!null?===?!!undefined??//?true
        復(fù)制代碼

        Object.getPrototypeOf(Object.prototype)

        JavaScript?中第一個(gè)對象的原型指向?null?。

        Object.getPrototypeOf(Object.prototype)??//?null
        復(fù)制代碼

        + 運(yùn)算 與 Number()

        let?a?=?undefined?+?1??//?NaN
        let?b?=?null?+?1??//?1
        Number(undefined)??//?NaN
        Number(null)??//?0
        復(fù)制代碼

        JSON

        JSON.stringify({a:?undefined})??//?'{}'
        JSON.stringify({b:?null})??//?'{b:?null}'
        JSON.stringify({a:?undefined,?b:?null})??//?'{b:?null}'
        復(fù)制代碼

        let undefiend = 'test'

        function?test(n)?{
        ????let?undefined?=?'test'
        ????return?n?===?undefined
        }

        test()???????????//?false
        test(undefined)??//?false
        test('test')?????//?ture

        let?undefined?=?'test'??//?Uncaught?SyntaxError:?Identifier?'undefined'?has?already?been?declared
        復(fù)制代碼

        深入探索

        為什么 typeof null 是 object?

        typeof null?輸出為?'object'?其實(shí)是一個(gè)底層的錯誤,但直到現(xiàn)階段都無法被修復(fù)。

        原因是,在?JavaScript?初始版本中,值以?32位?存儲。前?3位?表示數(shù)據(jù)類型的標(biāo)記,其余位則是值。
        對于所有的對象,它的前?3位?都以?000?作為類型標(biāo)記位。在?JavaScript?早期版本中,?null?被認(rèn)為是一個(gè)特殊的值,用來對應(yīng)?C?中的?空指針?。但?JavaScript?中沒有?C?中的指針,所以?null?意味著什么都沒有或者?void?并以?全0(32個(gè))?表示。

        因此每當(dāng)?JavaScript?讀取?null?時(shí),它前端的?3位?將它視為?對象類型?,這也是為什么?typeof null?返回?'object'?的原因。

        為什么 Object.prototype.toString.call(null) 輸出 '[object Null]'

        toString()?是?Object?的原型方法,調(diào)用該方法,默認(rèn)返回當(dāng)前對象的?[[Class]]?。這是一個(gè)內(nèi)部屬性,其格式為?[object Xxx]?,其中?Xxx?就是對象的類型。

        JavaScript 萬物皆對象,為什么 xxx.toString() 不能返回變量類型?

        這是因?yàn)?各個(gè)類中重寫了?toString?的方法,因此需要調(diào)用?Object?中的?toString?方法,必須使用?toString.call()?的方式調(diào)用。
        對于?Object?對象,直接調(diào)用?toString()? 就能返回?'[object Object]'?。而對于其他對象,則需要通過?call / apply?來調(diào)用才能返回正確的類型信息。

        為什么 == 和 === 對比會出現(xiàn) true 和 false ?

        很多文章說:undefined?的布爾值是?false?,?null?的布爾值也是?false?,所以它們在比較時(shí)都轉(zhuǎn)化為了?false?,所以?undefined == null?。
        實(shí)際上并不是這樣的。
        ECMA?在?11.9.3?章節(jié)中明確告訴我們:

        1. If?x?is?null?and?y?is?undefined, return?true.
        2. If?x?is?undefined?and?y?is?null, return?true.

        這是?JavaScript?底層的內(nèi)容了,至于更深入的內(nèi)容,如果有興趣可以扒一扒?JavaScript?的源碼。
        至于?==?和?===?的區(qū)別,后續(xù)我會在其他文章中詳細(xì)說明。敬請期待!

        為什么?null + 1?和?undefined + 1?表現(xiàn)不同?

        這涉及到?JavaScript?中的隱式類型轉(zhuǎn)換,在執(zhí)行?加法運(yùn)算?前,隱士類型轉(zhuǎn)換會嘗試將表達(dá)式中的變量轉(zhuǎn)換為?number?類型。如:'1' + 1?會得到結(jié)果?11。

        • null?轉(zhuǎn)化為?number?時(shí),會轉(zhuǎn)換成?0
        • undefined?轉(zhuǎn)換為?number?時(shí),會轉(zhuǎn)換為?NaN

        至于為什么執(zhí)行如此的轉(zhuǎn)換方式,我猜測是?JavaScript?早期的一個(gè)糟糕設(shè)計(jì)。

        從語言學(xué)的角度來看:
        null?意味著一個(gè)明確的沒有指向的空值,而?undefined?則意味著一個(gè)未知的值。
        在某種程度上,?0?意味著數(shù)字空值。
        這雖然看起來有些牽強(qiáng),但是我在這一階段能所最能想到的可能了。

        為什么 JSON.stringify 會將值為 undefined 的內(nèi)容刪除?

        其實(shí)這條沒有很好的解釋方式,?JSON?會將?undefined?對應(yīng)的 key 刪除,這是?JSON?自身的轉(zhuǎn)換原則。

        在?undefined?的情況下,有無該條數(shù)據(jù)是沒有區(qū)別的,因?yàn)樗麄冊诒憩F(xiàn)形式上并無不同:

        let?obj1?=?{?a:?undefined?}
        let?obj2?=?{}

        console.log(obj1.a)??//?undefined
        console.log(obj2.a)??//?undefined
        復(fù)制代碼

        但需要注意的是,你可能在調(diào)用接口時(shí),需要對?JSON?格式的數(shù)據(jù)中的?undefied?進(jìn)行特殊處理。

        為什么 let undefiend = 'test' 可以覆蓋掉 JavaScript 自身的 undefined?

        JavaScript?對于?undefined?的限制方式為全局創(chuàng)建了一個(gè)只讀的?undefined?,但是并沒有徹底禁止局部?undefined?變量的定義。

        據(jù)說在?JavaScript?高版本禁止了該操作,但我沒有準(zhǔn)確的依據(jù)。

        請?jiān)谌魏螘r(shí)候,都不要進(jìn)行?undefined?變量的覆蓋,就算是你的?JSON?轉(zhuǎn)換將?undefined?轉(zhuǎn)換為?''?。也不要通過該操作進(jìn)行,這將是及其危險(xiǎn)的行為。

        總結(jié)

        關(guān)于使用 undefined 還是 null

        這是一條公說公有理婆說婆有理的爭議內(nèi)容。
        本人更傾向于使用?null?,因?yàn)檫@是顯示定義空值的方式。我并不能給出準(zhǔn)確的理由。

        但關(guān)于使用?undefined?我有一條建議:
        如果你需要使用?undefined?定義空值,請不要采取以下兩種方式:

        • let a;
        • let a = undefined;

        進(jìn)而采取下面這種方式顯式聲明?undefined?:

        • let a = void 0;

        結(jié)語

        用了兩天時(shí)間,終于將?undefined?和?null?的基本區(qū)別搞定了。

        如果大家認(rèn)為有任何需要?補(bǔ)充?的,或者有?錯誤?內(nèi)容,請盡快在評論區(qū)留言。

        關(guān)于本文

        作者:sincenir

        https://juejin.cn/post/7051144396615450655?

        技術(shù)交流群


        我組建了技術(shù)交流群,里面有很多?大佬,歡迎進(jìn)來交流、學(xué)習(xí)、共建?;貜?fù)加群即可。





        ???“分享、點(diǎn)贊、在看” 支持一波??




        瀏覽 42
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            操逼视频啊啊啊 | 黄色成人播放免费 | 在线免费视频a | 久久一级毛片一区二区性色xxxx | 亚洲av无码在线看 | 嫩草精品福利视频在线观看 | 6070老女人毛片A片视频 国产精品色婷婷7777777 | 免费动漫黄 | 91精品国久久久久久无码一区二区三区 | 亚洲成人大香蕉 |