跳至內容
Astera Technology

字串和數字一樣寫法,也未必是同一個值

比對數字、文字和空值時,別只看畫面上的字。

下載完整個案資料及參考答案 ↓

先追這段程式

用 === 和 == 比較三組值。輸出為方便閱讀把 a、b 轉成文字;下表補回原本類型,避免兩個「4」看來一樣便當作相等。

完整原始程式
const cases=[[4,'4'],[4,4],[null,undefined]];
console.log(JSON.stringify(cases.map(([a,b])=>({a:String(a),b:String(b),strict:a===b,loose:a==b}))));
確實的 console 輸出
[{"a":"4","b":"4","strict":false,"loose":true},{"a":"4","b":"4","strict":true,"loose":true},{"a":"null","b":"undefined","strict":false,"loose":true}]
值與執行位置
原值typeof 的結果=== / ==
4 / "4"number / stringfalse / true
4 / 4number / numbertrue / true
null / undefinedobject / undefinedfalse / true

結果為何如此

表內列的是 typeof 的結果。null 本身是 Null 類型的原始值;typeof null 回傳 "object" 是歷史行為,並不表示 null 是物件。=== 遇上不同類型便不相等;== 會依轉換規則判斷,null 和 undefined 在本例亦相等。兩種運算都不代替輸入驗證。NaN 與自身用 === 比較仍是假;物件則看是否同一參照。

比較另一種寫法

先把兩邊轉成文字再比較,問的已是顯示字眼是否相同,不再是原值是否相同。另要留意 typeof null 是 object,這個歷史行為不代表 null 可讀屬性。

另開的有限例子
console.log(JSON.stringify({rendered:String(4)===String('4'),original:4==='4',nullType:typeof null}));
另一寫法的輸出
{"rendered":true,"original":false,"nullType":"object"}

試清邊界

兩邊類型相同,=== 是否一定為真?

查看參考答案

不是。4===5、NaN===NaN 都是假;分別建立的物件也不是同一參照。

重新建立的邊界例子
const object={};console.log(JSON.stringify({different:4===5,nan:NaN===NaN,separate:{}==={},same:object===object}));
邊界例子的輸出
{"different":false,"nan":false,"separate":false,"same":true}

原始例子檔案