的隐式强制类型转换规则)
在本文开始前向读者推荐这篇文章的灵感来源《你不知道的JavaScript》具体来源为中卷第一部分第4章4.5小节“宽松相等和严格相等”。本文主要根据书中内容和笔者思考总结出宽松相等时隐式强制类型转换的规则不讨论其他比较的算法如Object.is()。并给出部分示例。注意个人总结难免疏漏如有错误希望读者能指出避免后续误导其他读者一、规则比较类型相同直接比较值是否相等。对象比较时指向同一个值时即视为相等而且对象比较时宽松相等和严格相等没有区别。此处涉及对象知识不再赘述。比较类型不同布尔转数字≈对象ToPromitive 抽象操作valueOf方法和toString方法字符串转数字。特殊情况null和undefined只和对方或者自身相等NaN ! NaNNaN不等于任何值0 -0二、特殊情况// 1. null 和 undefined console.log(null undefined); // true console.log(null undefined); // false // 2. NaN console.log(NaN NaN); // false console.log(NaN anyValue); // false console.log(NaN NaN); // false // 3. 0 和 -0 console.log(0 -0); // true console.log(0 -0); // true三、比较类型不同布尔转数字≈对象ToPromitive 抽象操作valueOf方法和toString方法字符串转数字。1、布尔值转数字值false - 0true - 12、对象ToPromitive 抽象操作当比较的双方仅有一方为对象时会触发这个操作。ToPromitive 抽象操作会根据传入的hint值来判断是先调用valueOf()方法还是toString()方法。hint值有三种number、string和default。如果提示是number先调用valueOf()如果返回的不是基本类型再调用toString()。如果提示是string先调用toString()如果返回的不是基本类型再调用valueOf()。如果提示是default先调用valueOf()如果返回的不是基本类型再调用toString()。但是在宽松相等比较的情况下不用考虑这么多只需要记住js内置常用的只有Date和String优先调用toString()方法其他都可以按valueOf()先调用非自定义的情况下。但是前提是valueOf()方法必须返回的是基本类型数字、字符串、布尔如果是非基本类型则会调用toString()方法。直接讲不易理解我们从例子来入手例[] false判断类型不同-隐式类型转换[]为对象非Date和String调用valueOf()方法会返回数组则调用toString()返回空字符串-转换布尔false布尔转数字false转为0-空字符串和0相比类型不同优先转字符串为数字空字符转数字为0-0和0比类型相同比较值值也相同判断为true。3、字符串转数字字符串内容转换结果示例仅包含数字整数对应的整数123→123包含小数点浮点数对应的浮点数3.14→3.14前导空格或制表符被忽略解析有效数字 -5 →-5十六进制格式对应的十进制数0xFF→255空字符串或仅空格0→0 →0包含非数字字符非前导NaN123abc→NaN1.2.3→NaN完全不包含数字NaNhello→NaNtrue→NaN四、例题可以先尝试做一下下面例题0 false false [] 0 {} [] ![] [null] foo [foo] 42 true 42 false答案0 false // true false // true [] // true 0 {} // false [] ![] // true [null] // true foo [foo] // true 42 true // false 42 false // false这里解析几个比较特殊的对于空对象{}由于对象的valueOf返回的是自身不是基本数据类型导致会跳过valueOf转而调用toString()而toString返回值为[object Object]转成数字是NaNNaN和任意值比较均不相等所以0 {}为false[] ![] // true这看起来确实很奇怪但一步步来就会明白原因。![]会强制类型转换为false所以就变成了[] false这个例子在三.3讲过不再赘述。[null]调用toString方法会返回空字符串最后来看这个例子42 true // false 42 false // false。42作为一个真值居然既不等于false也不等于true然而这个想法有点先入为主了。 true不代表判断比较的前者是否是真值同样的 false也不代表判断比较的前者是否是假值而是要按照规则一步步比较先转换布尔值为数字值再转换字符串为数字值最后得到 42 1 和 42 0。到这里显而易见答案确实都是false。所以《你不知道的JavaScript》的作者在书中建议无论什么情况下都不要使用 true 和 false比较的前者是真值还是假值与本身没有关系最后欢迎大家批评指正