<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入學習下 null 和 undefined 區(qū)別

          共 3915字,需瀏覽 8分鐘

           ·

          2022-03-03 17:05

          作者:sincenir

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

          前言

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

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

          簡單區(qū)分

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

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

          MDN 中給出的定義

          null

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

          undefined

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

          一張神奇的圖片

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

          表現(xiàn)形式

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

          typeof

          typeof?null??//?'object'
          typeof?undefined??//?'undefined'
          復制代碼

          Object.prototype.toString.call

          typeof?null??//?'[object?Null]'
          typeof?undefined??//?'[object?Undefined]'
          復制代碼

          == 與 ===

          null?==?undefined??//?true
          null?===?undefined??//?false
          !!null?===?!!undefined??//?true
          復制代碼

          Object.getPrototypeOf(Object.prototype)

          JavaScript?中第一個對象的原型指向?null?。

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

          + 運算 與 Number()

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

          JSON

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

          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
          復制代碼

          深入探索

          為什么 typeof null 是 object?

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

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

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

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

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

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

          這是因為 各個類中重寫了?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?,所以它們在比較時都轉(zhuǎn)化為了?false,所以?undefined == null?。
          實際上并不是這樣的。
          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ù)我會在其他文章中詳細說明。敬請期待!

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

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

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

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

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

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

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

          在?undefined?的情況下,有無該條數(shù)據(jù)是沒有區(qū)別的,因為他們在表現(xiàn)形式上并無不同:

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

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

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

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

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

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

          請在任何時候,都不要進行?undefined?變量的覆蓋,就算是你的?JSON?轉(zhuǎn)換將?undefined?轉(zhuǎn)換為?''?。也不要通過該操作進行,這將是及其危險的行為。

          總結(jié)

          關于使用 undefined 還是 null

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

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

          • let a;
          • let a = undefined;

          進而采取下面這種方式顯式聲明?undefined?:

          • let a = void 0;


          瀏覽 22
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一起操网站 | 国产色小视频 | 日本东京热手机播放 | 国产精品久久久久久久久久妞妞 | 亚洲2019免费视频 |