首先我们定义一个空的数组:
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,血的教训啊!!!