ECMAScript中的隐式转换 == 会先将两边转换成相似的类型,再执行比较;
①、如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;
②、如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值
③、如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较,如果对象没有valueOf()方法,则调用 toString();
顺便提一下,valueOf() 方法可返回 Boolean 对象的原始值。[ ] 和 { } 都是属于引用类型,js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引用数据类型的变量存储在堆中,引用类型数据的地址存在栈中,当访问基础类型变量时,直接从栈中取值。当访问引用类型变量时,先从栈中读取地址,在根据地址到堆中取出数据;
①、根据运算符优先级 ,! 的优先级是大于 == 的,所以先会执行 ![]
!可将变量转换成boolean类型,null、undefined、NaN以及空字符串(‘’)取反都为true,其余都为false。
所以 ! [] 运算后的结果就是 false
也就是 [] == ! [] 相当于 [] == false
②、根据上面提到的规则(如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1),则需要把 false 转成 0
也就是 [] == ! [] 相当于 [] == false 相当于 [] == 0
③、根据上面提到的规则(如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较,如果对象没有valueOf()方法,则调用 toString())
而对于空数组,[].toString() -> ‘’(返回的是空字符串)
也就是 [] == 0 相当于 ‘’ == 0
④、根据上面提到的规则(如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值)
Number(‘’) -> 返回的是 0
相当于 0 == 0 自然就返回 true了
总结:
[] == ! [] —> [] == false —> [] == 0 -> ‘’ == 0 —> 0 == 0 —> true