Fork me on GitHub

记js中一些类型转换的坑

类型转换从初学 js 时就接触,但一直没能记牢,最近面试吃了大亏,自尊心深受打击,还是好好整理一下吧 🌚

显式转换

Number() 转换规则

Z9DMgikfOat5spS

Boolean() 转换规则

CmPU5EbuJyFLKXo

String() 以及不同对象 toString() 转换规则

FDGyP9dIbaKXTLC

隐式转换

== 操作符隐式转换

  1. 有且仅有一个操作数是 Boolean 会先将 Boolean 转化为 Number (true -> 1, false -> 0)
  2. 一个操作数是 String 另一个是 Number 会先将 String 转化为 Number
  3. 有且仅有一个操作数是对象类型则会调用 valueOf()、toString() 进行转化

举 🌰 子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'true' == true // false
// 根据“规则 1”所知第一次将会转化为 `'true' == 1`,然后转化后又会符合“规则 2”,所以将重新转化为 `NaN == 1`

[1] == 1 // true
// 数组根据“规则 3”调用 valueOf() 依然为 `[1] == 1`,然后通过 toString() 转为 `'1' == 1`,最后根据“规则 2”转为 `1 == 1`

null == false // false
null == true // false
undefined == false // false
undefined == true // false
// 同为基本类型并且不符合 3 种规则中任意一种,所以都不进行转换,结果全为 false

[1, 2, 3] == [1, 2, 3] // false
// 这个没规则符合不会进行转换

+ 号运算符隐式转换

  1. 若 + 号两侧其中一个为字符串类型,那么会将另一侧也转为字符串类型,然后进行字符串拼接
  2. 若 + 号两侧其中一个为数字类型,那么会将另一侧也转为数字类型,然后进行计算
  3. 若 + 号右侧为对象类型,会先将它转化为字符串类型
  4. 若 + 号左侧声明了一个大括号那种对象,很多情况下 js 引擎会将它认成一个代码块而忽略计算
  5. 若 + 号左侧没内容,会先将右侧内容转为数字类型

举 🌰 子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
5 + '1' // '51'
'5' + 1 // '51'

'foo' + + 'bar' // 'fooNaN'
// 这个例子中第 2 个 + 号和 'bar' 是一起的,所以要按照“规则 2”来转换,
// 等于 'foo' + Number('bar') -> 'foo' + 'NaN'

[] + [] // ''
// 两侧通过 valueOf()、toString() 转化都得到 '',所以拼接后依然为一个空字符串

[] + {} // '[object Object]'
// 左侧通过转化得到 '',右侧通过转化得到 [object Object],所以拼接后就是最终结果

{} + [] // 0
// 这个莫名其妙的结果是因为 js 将 {} 解析成了一个代码块,只有 +[] 参与了运算

{} + {} // '[object Object][object Object]'
// 这个结果和“规则 4”有出入,测试环境为 Chrome 79.0.3945.88

- 号运算符

  • 若 - 号两侧不为数字类型则全转成数字类型后再进行计算
  • 若 - 号左侧没内容,会先将右侧内容转为数字类型

举 🌰 子

1
2
3
4
5
[1] - false // 1
// 等于 '1' - false -> 1 - 0 -> 1

-true
// 等于 -Number(true) -> -1

一些注意点

1
2
NaN == NaN // false
undefined == null // true,这是规定