很多时候我们会碰到这样的面试题:[]==![]的值是什么,这种貌似很简单的题目往往会有个意料之外的答案。比如这道题的答案就是true,那么为什么呢,我们来分析一下。
首先我们根据表达式规则可知,先算出![]的值,然后执行==运算符,我们知道取反运算符!的运算规则是针对值的布尔值取反,对固定六个值取反为true,其他值取反为false。这六个固定值为:"",null,undefined,NaN,false,0(包括+0和-0)。所以我们可知,上面我们要算的值为false。然后我们再计算==表达式值。
使用==,!=进行两个不同类型值的比较涉及到一个知识点:抽象相等比较算法。比较大致规则如下:
- 当两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回
true - 如果一个操作数是
null,另一个操作数是undefined,则返回true - 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
- 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
- 如果操作数之一是
Boolean,则将布尔操作数 转换为1或0。- 如果是
true,则转换为1 - 如果是
false,则转换为0
- 如果是
- 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的
valueOf()和toString()方法将对象转换为原始值。
- 如果操作数具有相同的类型,则将它们进行如下比较:
String:true仅当两个操作数具有相同顺序的相同字符串时才返回Number:true仅当两个操作数具有相同的值时才返回。+0,-0视为相同的值。如果任一操作数为NaN,则返回falseBoolean:true仅当操作数为两个true或两个false时才返回true
所以跟着上面的思路,我们可以梳理出接下来转换的步骤:
![]根据运算规则得到值为布尔类型false- 根据抽象相等比较算法,左边是一个对象,取其
valueof值,为"" - 接下来是字符串与
false比较,问题变成了Number("")==0,这个时候我们很容易知道最终结果为true
补充内容:
抽象相等比较算法涉及到ECMAScript规范,我们从规范中其实可以更好的看到事情的本质。
参考文档: