资讯专栏INFORMATION COLUMN

[JavaScript 随笔] 理解严格相等、非严格相等和隐式类型转换

rickchen / 1505人阅读

摘要:显然,相等判断是基于数字比较的,而条件判断是基于布尔值。严格相等严格相等的逻辑相对简单粗暴,如果类型不同,就不考虑隐式转换了,直接为假。

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

相关文章

  • 深入理解JavaScript类型转换

    摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...

    W4n9Hu1 评论0 收藏0
  • 深入理解JavaScript类型转换

    摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...

    niuxiaowei111 评论0 收藏0
  • 深入理解JavaScript类型转换

    摘要:等同于等同于其他类型和布尔类型之间的比较如果是布尔类型,则返回的结果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作为一门弱类型语言,我们在每天的编写代码过程中,无时无刻不在应用着值类型转换,但是很多时候我们只是在单纯的写,并不曾停下脚步去探寻过值类型转换的内部转换规则,最近通过阅读你...

    shuibo 评论0 收藏0
  • 解析JavaScript判断两个值相等的方法

      本篇文章主要是讲述在JavaScript中判断两个值相等,不要认为很简单,要注意的是在JavaScript中存在4种不同的相等逻辑。  ECMAScript 是 JavaScript 的语言规范,在ECMAScript 规范中存在四种相等算法,如下图所示:  上图中每个依次写下来,很多前端应该熟悉严格相等和非严格相等,但对于同值零和同值却不熟悉,现在就依次下面四种方法。  同值  同值零  非...

    3403771864 评论0 收藏0

发表评论

0条评论

rickchen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<