摘要:显然,相等判断是基于数字比较的,而条件判断是基于布尔值。严格相等严格相等的逻辑相对简单粗暴,如果类型不同,就不考虑隐式转换了,直接为假。
JavaScript 中大概有这几种 “类型”:
undefined
null
string
boolean
number
object
function
之所以在 “类型” 上加了双引号,是因为严格来说,null 的类型是 object。但本文讨论的主题包括了关于 null 的类型转换,它和 object 不同,所以多带带列出来了。这点请根据上下文强行区分一下,不是bug、不是bug、不是bug。
有趣的例子"0" == 0; // true 0 == ""; // true "0" == ""; // false
这里展示的是相等比较的非传递性。即,如果有 a == b, b == c,并不代表 a == c。
如果说
"1" == true; "0" == false;
这两个是常识,那对于一些特殊的字符串,你能正确判断吗?
"001" == true; "002" == false; // 注意! "0x0" == false; " " == false;非严格相等(==)
当使用 == 比较,并且两侧的类型不同时,会触发隐式类型转换。标准中定义的转换规则很长,其核心就是,1、类型不同时,尽量转成 数字 比较;2、特例。(类型相同就按该类型的值判断,不特殊说明了,难道 "123" 还能等于 "456" 不成?)
关于特例,其实也就是 null 和 undefined 。也就是说,以下几个表达式是永远为 true 的。
undefined == null; null == undefined; NaN != NaN; // 注意! null != 非null; // 注意!null 与非 null 值永远是不等的
所以也不需要再去深追为什么 undefined 和 null 是相等的,因为按照“规则”已经无法解释了,这是一种“约定”。OK,剩下的情况是转数字。
null 的数值是 0
undefined 的数值是 NaN
true 是 1,false 是 0
至于字符串,嗯,有点复杂
object:调用 toString 或 valueOf 后转成基本类型,再转数字
第一条,在这里没用,因为涉及到 null 的比较时,除非 null == null,其他情况都是不等的。即
null != 0;
第二条,在这里没用,因为涉及到 NaN 的比较时,都是不等。
第三条,有点用,很有用!
1 == true; // 对 2 == true; // 错!
第四条,麻烦。80% 情况下,对于 "123" 转成 123,"abc" 转成 NaN,"" 转成 0,这三条记住就可以了。
"123" == 123; "" == 0; "abc"; // 转成数值是 NaN
另外的情况,由于字符串的组合形式各种各样,很难三言两语总结完,大致有:
空白字符串转成 0," " == 0
十六进制、八进制正常转换,"0xff" == 255
数字字符串会忽略首尾空白字符,正常转," 123 " == 123
数字字符和其他字符混合时,转成 NaN,如 "123abc"
现在回头去看“有趣的例子”,是不是一目了然。(嗯,不谢)
条件判断暂且把 if - else 和 condition ? a : b; 中的判断情况称为条件判断吧。(场景还有取反、for、while 等)
等于 true 的值一定是 truthy,但等于 false 的值不一定是 falsy 。
例
new Boolean(false) == false; // 这个没问题吧? new Boolean(false) ? "a" : "b"; // 表达式的值是 "a"!
只能说,条件判断中对真假的判定和相等判断是不一样的。 显然,相等判断是基于数字比较的,而条件判断是基于布尔值。
关于布尔值的转换规则:
null, undefined, NaN 都是 false
字符串,仅当空字符串("")时为 false,其他都是 true
object,都是 true (仅 null 除外)
我见过其他一些相等判断的技巧:
!!x == true; +x == 123;
取反操作会把变量强转成 boolean;一元 + 会把变量强转成 number。
也见过一些用的不太合适的地方(?):
if (!!x) // ...
在条件判断中本身会做强转的操作,为了可读性?不见得有提高。
严格相等(===)严格相等的逻辑相对简单粗暴,如果类型不同,就不考虑隐式转换了,直接为假。如果类型相同:
布尔、数字、字符串就看字面值是否相等
object,看引用是否相同
主要是考虑什么时候用 ==,什么时候用 === 。
很简单,只有在要求类型相同时,才用 ===,否则用 ==
有些场景的确只有非严格相等才能做,比如
var b = new Boolean(false); b === false // 竟然是错的 b == false // 对 b ? "a" : "b" // 竟然是 "a"
结论就是当涉及到对象比较时,稍微斟酌一下。而对于像 typeof x 它一定会返回 string,这时用 == 比较就更合适一些。
小结涉及到 == 比较,并且需要隐式转换时,会转成 number。
涉及到条件判断,自然是转成 boolean。
涉及到二元 +、- 等数值计算时,从左至右优先转成 number,除非是遇到 string,则做字符串拼接操作。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/91574.html
摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...
摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...
摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...
本篇文章主要是讲述在JavaScript中判断两个值相等,不要认为很简单,要注意的是在JavaScript中存在4种不同的相等逻辑。 ECMAScript 是 JavaScript 的语言规范,在ECMAScript 规范中存在四种相等算法,如下图所示: 上图中每个依次写下来,很多前端应该熟悉严格相等和非严格相等,但对于同值零和同值却不熟悉,现在就依次下面四种方法。 同值 同值零 非...
阅读 3616·2021-09-22 15:15
阅读 3497·2021-08-12 13:24
阅读 1290·2019-08-30 15:53
阅读 1794·2019-08-30 15:43
阅读 1121·2019-08-29 17:04
阅读 2774·2019-08-29 15:08
阅读 1546·2019-08-29 13:13
阅读 3055·2019-08-29 11:06