天天看點

[]==[]為false,[]==![]為true

JS真是博大精深啊,看似相等,其實不等,而看似不等,卻是相等。

沒錯,你沒有看錯,JS就是這麼不可思議!

這個問題涉及到JS基礎,通常會出現在前端面試題中,剛開始我對于此問題也是存在疑惑的,但隻要明白其原理也很好了解。

一、[]==[]為false

在JS中,數組是屬于引用型資料類型,是以“==”左右兩邊所表示的實際隻是數組的所在的位址而已。在建立一個新數組時,其位址均不相同,是以[]==[]最終傳回false。

二、[]==![]為true

這個就有點難了解了,按照正常思維來看,符号“!”代表的是取反,是以“==”兩邊的值應該不等才是。

這個就涉及到了JS中的資料類型轉換的問題,當我們使用“==”來對資料進行比較時,若兩個資料類型不一緻,JS會先按照一定規則将資料轉換為同一資料類型後再進行比較。

1. 若其中一個資料類型為數值,那麼另一個資料類型會先轉換成數值然後再與之比較

① 字元串與數值

console.log(""==1);   // false
console.log(""==0);   // true
console.log("hello"==1);   // false
console.log("000"==0);   // true
console.log("666"==666);   // true
           

需要注意的是,

"hello"

轉換為數字是

NaN

② 布爾值與數值

console.log(true==1);   // true
console.log(true==2);   // false
console.log(false==0);   // true
           

很簡單,

true

被轉換為

1

false

③ 數組與數值

console.log([]==0);   // true
console.log([1]==1);   // true
console.log(["1"]==1);   // true
console.log([1,2]==1);   // false
console.log([true]==1);   // false
           

需要注意的是,數組會先通過調用

toString()

轉換為字元串後再轉換為數值,比如

[true]

轉換為字元串後為

"true"

,然後再轉換為數值是

NaN

,是以

[true]==1

傳回

false

事實上,數組、對象和函數在與其他基本資料類型進行比較時都會先轉換為字元串,然後再轉換為相應的資料類型(這裡指的資料類型也可能需要轉換,總之最後比較時一定是同一資料類型)進行比較,在此就不再一一舉例了。

④ null、undefined和NaN

這三個是個特例,他們比較特殊:

a) null==undefined為true;

b) null和undefined不會進行資料轉換;

c) NaN不與任何值相等,甚至包括它自己!

我們來看幾個例子:

console.log(null==undefined);   // true
console.log(null==0);   // false
console.log(null==false);   // false
console.log(null=="");   // false
console.log(undefined==0);   // false
console.log(undefined==false);   // false
console.log(undefined=="");   // false
console.log(undefined==NaN);   // false
console.log(null==NaN);   // false
console.log(NaN==NaN);   // false
           

2. 若其中一個資料類型為布爾值,則會先将其轉換成數值再進行比較

console.log(true=="001");   // true
console.log(true==[]);   // false
console.log(true==["true"]);   // false
console.log(true==[true]);   // false
console.log(true==[1]);   // true
           

剛開始接觸若不知道其原理,這些其實都很容易判斷錯誤,但知道轉換規則之後也比較好判斷。

我們可以看到,

==

左側均為

true

,而右側均不是布爾值類型,是以不管三七二十一,先将

true

轉換成數值

1

,然後再根據上面 1 中所講與數值類型比較的轉換規則,将右側值統統進行資料類型轉換,轉換後如下所示:

console.log(1==1);   // true
console.log(1==0);   // false
console.log(1==NaN);   // false
console.log(1==NaN);   // false
console.log(1==1);   // true
           

3. “!” 為邏輯非,在操作非布爾值類型的資料時,會将該資料類型先轉換為布爾值後再取反

console.log(!"");   // true
console.log(!"false");   // false
console.log(!2);   // false
console.log(![]);   // false
console.log(!["false"]);   // false
console.log(!NaN);   // true
           

關于其他資料類型轉布爾值,以下均傳回true:

① 非空字元串

② 非零數值

③ 數組

④ 對象

⑤ 函數

了解了以上資料類型轉換規則之後在來了解

[]==![]

的問題就很簡單了:

① 将

==

右側數組轉換為布爾值後再取反,轉換後相當于

[]==false

② 根據“比較前布爾值轉數值”規則,轉換後相當于

[]==0

③ 根據“比較前數組遇數值先轉字元串後轉數值”規則,轉換後相當于

0==0

本文重點總結

① 相等操作符,不同資料類型會根據一定規則轉換為同一資料類型再比較

② 數組與數組比較,比較的是其引用

③ 不同類型比較,遇數值則轉數值,布爾值自身轉數值

④ 非空非零引用型,轉為布爾均為真

繼續閱讀