??? 最近看review同事的代碼,發(fā)現(xiàn)他定義一個變量但不賦值時,經(jīng)常將這個其設(shè)為null(let a = null;),而非我經(jīng)常只定義不賦值時的undefined(let a;),所以下意識的就得自己一定是忽略了什么,于是花了點點時間來了解了下二者的卻別,帶著下面的問題為,我們來開始我們的剖析。
定義變量但"不賦值"的話,到底需不需要將其設(shè)為null?
一、相似性
? ? 老實說在js中將一個變量設(shè)為null或undefined幾乎沒什么區(qū)別,幾乎是等價的。在if語句中二者都會被轉(zhuǎn)化成false,做相等運算時,二者還相等。?
? ? if (null) { console.log('null is false') }? ? =====>? ? 輸出'null is false'
? ? if (undefined) { console.log('null is false') }? ? =====>? ? 輸出'undefined is false'
? ? undefined? == null? ??=====>? ? 輸出true
二、既然二者如此相似,為什么js還要設(shè)置這樣的兩個值?
? ? 原來JavaScript誕生之初,最初像Java一樣,只設(shè)置了null作為表示"無"的值。
? ? ① null像在Java里一樣,被當(dāng)成一個對象。但是,JavaScript的數(shù)據(jù)類型分成基本類型和引用類型兩大類,Brendan Eich覺得表示"無"的值最好不是對象。
? ? ②?JavaScript的最初版本沒有包括錯誤處理機制,發(fā)生數(shù)據(jù)類型不匹配時,往往是自動轉(zhuǎn)換類型或者默默地失敗。Brendan Eich覺得,如果null自動轉(zhuǎn)為0(Number(null)? =====>? 輸出0),很不容易發(fā)現(xiàn)錯誤,所以Brendan Eich又設(shè)計了一個undefined(Number(undefined)? =====>? 輸出NaN)。
三、二者目前的用法
? ? null表示"沒有對象",即該處不應(yīng)該有值。典型用法:
? ? ① 作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對象;
? ? ② 大家都知道js對象的老祖宗Object.prototype,但是大家有沒想過Object.prototype.__proto__是什么值,其實是null,而非undefined;
? ? undefined表示"缺少值",就是此處應(yīng)該有一個值,但是還沒有定義。典型用法:
? ? ① 變量被聲明了,但沒有賦值時,就等于undefined;
? ? ②?調(diào)用函數(shù)時,應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined;
? ? ③?對象沒有賦值的屬性,該屬性的值為undefined;
? ? ④?函數(shù)沒有返回值時,默認(rèn)返回undefined;
? ? 綜上幾點看來,個人覺得聲明的變量未賦值時還是按其默認(rèn)的undefined為好(若確定這個變量后面會被賦值成一個對象,設(shè)null也可),強行解釋,原由如下:
? ? ① 減少代碼量;
? ? ② 通常值設(shè)為null表示其值后面會設(shè)為一個對象,但是js作為一個弱類型的語言,變量有時基本類型引用類型都有可能被賦值上;
? ?③ null在做計算操作時會被轉(zhuǎn)換成0參與計算,當(dāng)定義的變量沒被賦上值,且參與了計算,頁面不會報錯,出現(xiàn)了bug不易發(fā)現(xiàn)。