我对js隐式转换终于不用再靠_猜_了!
一、前言
在项目开发或者面试中经常出现下面这种判断:
1 | console.log({} - {}); |
结果分别是:NaN、0、1,2、true、false
二、包装类
包装类是我们理解隐式转化的基础工具,是理解隐式转化的根基。
js 中包装类分为:Boolean()、Number()、String()。
Boolean()
Boolean()
只有两种值:true
和false
其中值为false
的称为falsey
或虚值
,分别包括 0、null、undefined、false、’’,NaN;
而值为true
的称为truth
,除了falsey
其他的返回都是true
Number()
Number()
的处理就分为对 基础类型 的处理和 引用类型 的处理。
基础类型
1 | console.log(Number(null)) // 0 |
其中为NaN
的数值分别有undefined
、null
、'1ab'
null
表示”没有对象”,即该处不应该有值。 undefined
表示”缺少值”,就是此处应该有一个值,但是还没有定义。
而'1ab'
为NaN
是因为字符串转换中出现了非数字的就会转换成NaN
引用类型
假如我们现在有下面这么一个对象:
1 | const obj = { |
如果用Number()
去取值的时候就会调用到valueOf()
方法,此时会返回 1 ,但如果改写 valueOf() { return {} }
的话就会去调用 toString()
, 此时返回 2
所以Number(引用类型)
的逻辑过程就是:
String()
String()
就是跟Number()
相反,先调用toString()
然后再看valueOf()
1 | const obj = { |
3 < 2 < 1 和 2 < 1 < 1
两个输出都是true
,第一个符合数学公式,第二个就涉及到隐式转换了
- 比较 2 < 1 结果为 fasle
- 现在就是 false < 1 ,Number(false) 为 0
- 现在就是 0 < 1, 结果为 true
三、隐式转换规则
boolean 隐式转换触发
- if
- switch
- while
- for(;;)
- &&
- ||
- !
- !!
- ? : 三元运算
number 隐式转换触发
用到数字运算符的地方都会进行转换:+ - * / == ~~ & | ~ ^ << <<<
string 隐式转换触发
+
且两边大于等于 1 个string
类型. 除了有 symbol
类型之外
1 | console.log(1 + '2' + '2'); // '122' |
- 用 + 包裹,全部就转换为字符串后相加操作
- +’2’ 会先进行 number 转换,变成 1 + 2 = 3,然后遇到 + 在进行 string 转换
- ‘A’ - ‘B’ 会先进行 number 转换,变成 NaN,然后 string 转换
- 同上
四、需要注意的点
1 | console.log((123).toString()); // 123 |
undefined
和null
并没有包装类,它们是基础类型,所以没有toString()
方法
五、面试题
1 | console.log([] == ![]); // true |
- 一看到
==
就会想到两边会进行Number
转换 Number([])
会调用到Array.prototype.toSting()
,得到的是一个空字符串''
,用Number
转换后就会变成 0- 右边
![]
会先进行Boolean
转换,[]
不是falsey
,所以Boolean([])
为true
!true
再进行Numebr
转换就会变成 0- 所以最终就是
0 == 0
,结果为 true
六、奇奇怪怪的题目
1 | 66.toString() // 报错: Invalid or unexpected token |