1.现象
偶然情况下看到了,这两个关系语句:
[] == []; // false
[] == ![]; // true
简单查了一些东西,一开始以为自己懂了,后来才发现原来是错觉,这里写篇小文章记录一下~
2.简单分析
[] == []
因为js中对象相等的判断是引用的判断,[]则是通过字面量的方式创建了一个长度为0的数组,数组也是一种对象,所以[] == []创建的两个数组比较结果自然是false
![] == []
![]是创建一个长度为0的数组,将其转化为布尔值后求反。所有对象的布尔值转化结果都是true(null是一个原始值,虽然typeof null的结果是"object",但是本质上不是对象,而是五类基本数据类型中的一种),所以这里的![]的结果是false
[]创建了一个长度为0的数组,但是这里将它作为一个关系操作符符的一个操作数,在另一个操作数![]不是对象,而是布尔值的时候,并没有直接执行其向布尔值的转化,而是执行了其向原始值(primitive value)的转化。对象到原始值的转化基本上都是对象到数字的转化,只有日期对象到原始值的转化是对象到字符串的转化,参考[类型转化,对象=>字符串](http://blog.csdn.net/qq_20659385/article/details/49534045)。因为字符串的valueOf方法没能返回一个原始值,则调用toString方法,返回一个长度为0的字符串,进而自然有:
false == “”; // true
3.关于隐式转换
以前总觉得js的隐式转换太给力了,以至于总有这样一种错觉:
1 == true; // true
12 == true; // true
"" == false; // true
"a" == true; // true
直到自己把它敲进了控制台才发现,原来现实却是这样的:
1 == true; // true
12 == true; // false
12 == false; // false
"" == false; // true
"a" == true; // false
"a" == false; // false
"true" == true; // false
"true" == false; // false
"false" == false; // false
"false" == false; // false
12 == "12"; // true
感觉整个人都不好了,后来才发现,原来关系操作符对操作数的转化,针对对象其实只是向原始值的转化,具体的应该满足“对象到原始值的转化基本上都是对象到数字的转化,只有日期对象到原始值的转化是对象到字符串的转化”。而原始值之间,或者说五种基本类型(number,string,undefined,null,boolean)之间的转化却并不是那么的给力,结果完全超出了预期(至少我的是这样),所以这时候或许还是更多的手动转换一下吧。
4.更多
不是好些教程说,假值只(undefined、null、0、-0、NaN、”” (空字符串)这几个吗?但是为啥
var o = Boolean(" "); //false,参数是n+1个空格构成的字符串,取n大于等于0
亲测FF,chrome中这种结果又是什么鬼?(IE中是true)感觉人都不好了!