"小和山的菜鸟们",为前端开发者提供技术相关资讯以及系列基础文章。为更好的用户体验,请您移至我们官网小和山的菜鸟们 (xhs-rookies.com/) 进行学习,及时获取最新文章。
看到隐式类型转换这个词时,很多开发者就已经头大了。而其转换时的各种猫腻,相信各位开发者们更是饱受其折磨。
接下来,本文会通过对 ECMAScript 官方文档和各大网站高赞文章进行系统性的总结,务必帮助大家在读完后彻底掌握此知识点。
划重点
你只需要搞清楚两个问题就好了!
- 类型会转换为哪几类?
- 什么时候该转化为哪类?
数学运算符中的类型转换
众所周知,在 JS 中并没有类型声明,所以任意两个变量或字面量,都可以做加减乘除。
1.减、乘、除
我们在对各种非Number类型进行数学运算时(- * / )时,会先将非Number类型转换为Number类型。
1 - fasle // 1, 首先将 false 转换为数字 0 , 然后再执行 1 - 0
null / 1 // 0, 首先将 null 转换为数字 0 , 然后再执行 0 / 1
1 * undefined // NaN, undefined 转换为数字是NaN
2.加法的特殊性
谨记三条规则(优先级从高到低):
- 当一侧为
String类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。 - 当一侧为
Number类型,另一侧为原始类型,则将原始类型转换为Number类型。 - 当一侧为
Number类型,另一侧为引用类型,将引用类型和Number类型转换成字符串后拼接。
1 + '1' // ’11’ (规则1)
1 + null // 1 (规则2)
1 + true // 2 (规则2)
1 + {} // '1[object object]'(规则3)
注: 原始类型( undefined、null、string、number、boolean、symbol(es6新增) )
引用类型(Object 、Array 、Date、RegExp 、Function )统称为Object类型
逻辑语句中的类型转换
当我们使用 if while for 语句时,我们期望表达式是一个 Boolean ,所以一定伴随着隐式类型转换。
1.单个变量
这里有个小 tips:
只有 null undefined '' NaN 0 false 这几个是 false,其他的情况都是 true,比如 {} , []。
2.使用 == 比较中的 5 条规则
-
规则 1:
NaN和其他任何类型比较永远返回fasle(包括和它自己)NaN == NaN // false -
规则 2:
Boolean和其他任何类型比较,Boolean首先会被转换为Nmuber类型true == 1 // true true == '1' // false, 先把 true 变成 1,而不是先把 ‘1’ 变成true -
规则 3:
String和Number比较,先将String转换为Number类型1 == '1' // true, '1' 会先变成 1 '' == 0 // true, '' 会首先变成 0 -
规则 4:
null == undefined比较结果是true,除此之外,null、undefined和其他任何结果的比较值都为false。null == undefined // true null == '' // false null == 1 // false null == false // false undefined == '' // false undefined == 1 // false undefined == false // false -
规则 5:
原始类型和引用类型做比较时,引用类型会依照ToPrimitive(可在官方文档第七章节第一小节中找到)规则转换为原始类型ToPrimitive规则,是引用类型向原始类型转变的规则,遵循先valueOf后toString的模式,期望得到一个原始类型'[object Object]' == {} // 引用类型通过 toString 得到一个类型 '1,2,3,4' == [1, 2, 3, 4] // 同上
练练手吧
- [ ] == ! [ ]
- 第一步: ![] 会变为 false
- 这时,变为 [] == false
- 第二步:根据规则2,这时Boolean类型会先转换为 0
- 这时,变为 [] == 0
- 第三步:根据规则5,这时会调用ToPrimitive规则,[]调用valueOf 返回 [] , 不是原始类型 , 故接着调用
- toString , 返回 '' ;
- 这时,变为 '' == 0
- 第四步:根据规则3,string转换为number,''转换为0 故为true
- [ ] + { }
-
第一步: [] 调用
toString返回 '' -
第二步: {} 调用
toString返回'[object object]'故最后答案为
'object object'
总结
现在回头看看我们之前的两个问题
1.最后只会转换为 Boolean 或 Number 或 String
2.两种场景,数据类型和逻辑类型,对应相关规则进行转换
补充:ToPrimitive 规则发生在引用类型转换,通常是先调用 valueOf 方法、后调用 toString 方法、当调用 valueOf 后,若返回不是原始类型,继续调用 toString 方法,若返回还不是原始类型,则报 TypeError。
引用一张图片给大家做一个完美的总结
| 类型 | 值 | to Boolean | to Number | to String |
|---|---|---|---|---|
| Boolean | true | true | 1 | "true" |
| Boolean | false | false | 0 | "false" |
| Number | 123 | true | 123 | "123" |
| Number | Infinity | true | Infinity | "Infinity" |
| Number | 0 | false | 0 | "0" |
| Number | NaN | false | NaN | "NaN" |
| String | "" | false | 0 | "" |
| String | "123" | true | 123 | "123" |
| String | "123abc" | true | NaN | "123abc" |
| String | "abc" | true | NaN | "abc" |
| Null | null | false | 0 | "null" |
| Undefined | undefined | false | NaN | "undefined" |
| Function | function(){} | true | NaN | "function(){}" |
| Object | {} | true | NaN | "[object Object]" |
| Array | [] | true | 0 | "" |
| Array | ["abc"] | true | NaN | "abc" |
| Array | ["123"] | true | 123 | "123" |
| Array | ["123","abc"] | true | NaN | "123,abc" |
感谢
最后,感谢两位博主的文章帮助,能够站在巨人的肩膀上做一个以期能帮助大家的总结。
js 隐式装箱-ToPrimitive | {XFE} (sinaad.github.io)
[JavaScript 隐式类型转换,一篇就够了! (freecodecamp.org)](chinese.freecodecamp.org/news/JavaSc… - implicit-type-conversion/)
如果您对此文章还有疑惑,请 git 翻阅官方文档
ECMAScript 2015 Language Specification – ECMA-262 6th Edition (ecma-international.org)