alert([]==![])结果为true!求解释!
这个问题确实很奇怪,如下:
[] == false // true
![] // false,既然[] == false,那么 !false 为什么是 false? 应该是true
接下来详细的说下这个问题:
1,[]==![] 是 [] == (![]) 也就是 obj 与 bool 对比。比较规则为:obj 调用 valueOf () 方法,其返回值与 bool 比较。比较中有bool值,将bool值转化为 0 或 1, ;字符串与数值比较,会将字符串先转化为数值。
2,如果两个操作数类型相同的话,使用(==)与(===)没有区别。全等比较除了在比较前转换类型之外,(==)与(===)没有区别,那么在两个类型相同的操作数比较时(==)与(===)没有区别;
基本上遵循这两点规则,进行说明,
[] == false ,由于需要调用对象的valueOf 方法,所以实际比较为:
[].valueOf().toString() == false //true,由于 [].valueOf() 返回为对象,对象与bool比较,还会将对象在进行toString()转换。实际将[] 转为 "" 是 toSting()转换。
那么最重要的是知道 [] 不调用toString() ,本身到底是 真 还是 假。以最简单的方式验证:
alert(Boolean([])); //true
或下边的方式:
//1,弹出对话框,显示 1
if([]) {
alert(1);
}
//2,弹出对话框,显示 1
if([] == false) {
alert(1);
}
//3,报错:can't convert [] to primitive type
Array.prototype.toString = null;
if([] == false) {
alert(1);
}
//4,弹出对话框,显示 1
Array.prototype.toString = null;
if([]) {
alert(1);
}
那么经过这4步的验证,[] 实际为 真。
接下来就该验证 ![] 虽然没有比较,但是实际有没有调用toString() 或者 valueOf() .
Array.prototype.toString = function(){
alert('called toString')
}
Array.prototype.valueOf = function(){
alert('called valueOf');
}
if(![]){}; //没有输出called toString 和called valueOf,这里判断 !真
([]==![]) -> ([] == false) -> ([].toString()==false) -> (''==false) -> ('' == 0) -> (0 == 0) ->true
如果使用全等(===)的话,就不会出现这样的问题,因为不会转换类型后比较:
[]===![] // false
大概就是这样吧,可能有些地方说的不准确,大家帮完善吧。