首先我們定義一個空的數組:
var a = [ ];
數組a里面是空的沒有值,接下來我們打印:
console.log(!!a);
因為數組是空的,此處應該為false。
恰好相反,!!a為true。
但是,把空數組和布爾值比對后發現又出現了問題:
var a = [ ];
a == true;//false a == false;//true
這是個非常具有迷惑性的問題,與我們的認知好像是相反的,總有哪里出了問題。
后來發現這個與ECMA(我也不知道這個具體是干嘛的,反正是官方的)規范有關,里面有這么兩條:
- 第 7 條:If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- 第 9 條:If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
翻譯成中文就是:
如果x為Boolean,則轉化為數字進行比較;
如果x為Object ,String,Number等,轉化為原始值進行比較。
第一個好理解,第二個就有點問題了,什么是原始值?
ToPrimitive是一個內部的函數,查閱了網上的一些解釋,有一個說的很討巧,如果實在理解不來,就把ToPrimitive()當做join()。
這樣一來就好辦了,a是空數組,join后是空字符串,所以為false兩邊相等,返回true,沒問題。
而!!a則是因為發生了類型轉換,object轉型到布爾值,結果都是true。
所以:
var a = []; console.log(!!a);//true console.log(a);//[] console.log(a == false);//true console.log(a == true);//false
最后,項目中判斷一個數組是否為空,一定要用length,血的教訓啊!!!