17道题让你彻底理解JS中的类型转换

类型转换是将值从一种类型转换为另一种类型的过程(比如字符串转数字,对象转布尔值等)。任何类型不论是原始类型还是对象类型都可以进行类型转换,JavaScript 的原始类型有:number, string, boolean, null, undefined, Symbol。

本文将通过 17 道题目来深入的了解 JS 中的类型转换,通过阅读本文之后,你将能自信的回答出下面题目的答案,并且能够理解背后的原理。在文章的最后,我讲写出答案并解释。在看答案之前,你可以把答案写下来,最后再对照一下,便于找出理解有误的地方。

true + false 12 / "6" "number" + 15 + 3 15 + 3 + "number" [1] > null "foo" + + "bar" "true" == true false == "false" null == "" !!"false" == !!"true" ["x"] == "x" [] + null + 1 [1,2,3] == [1,2,3] {} + [] + {} + [1] ! + [] + [] + ![] new Date(0) - 0 new Date(0) + 0

类似于上面的这些问题大概率也会在 JS 面试中被问到, 所以继续往下读。

隐式 vs 显式类型转换

类型转换可以分为隐式类型转换和显式类型转换。

当开发人员通过编写适当的代码(如Number(value))用于在类型之间进行转换时,就称为显式类型强制转换(或强制类型转换)。

然而 JavaScript 是弱类型语言,在某些操作下,值可以在两种类型之间自动的转换,这叫做隐式类型转换。在对不同类型的值使用运算符时通常会发生隐式类型转换。比如 1 == null, 2 / "5", null + new Date() 。当值被 if 语句包裹时也有可能发生,比如 if(value) {} 会将 value 转换为 boolean类型。

严格相等运算符(===)不会触发类型隐式转换,所以它可以用来比较值和类型是否都相等。

隐式类型转换是一把双刃剑,使用它虽然可以写更少的代码但有时候会出现难以被发现的bug。

三种类型转换

我们需要知道的第一个规则是:在 JS 中只有 3 种类型的转换

to string

to boolean

to number

第二,类型转换的逻辑在原始类型和对象类型上是不同的,但是他们都只会转换成上面 3 种类型之一。

我们首先分析一下原始类型转换。

String 类型转换

String() 方法可以用来显式将值转为字符串,隐式转换通常在有 + 运算符并且有一个操作数是 string 类型时被触发,如:

String(123) // 显式类型转换 123 + '' // 隐式类型转换

所有原始类型转 String 类型

String(123) // '123' String(-12.3) // '-12.3' String(null) // 'null' String(undefined) // 'undefined' String(true) // 'true'

Symbol 类型转 String 类型是比较严格的,它只能被显式的转换

String(Symbol('symbol')) // 'Symbol(symbol)' '' + Symbol('symbol') // TypeError is thrown

Boolean 类型转换

Boolean() 方法可以用来显式将值转换成 boolean 型。

隐式类型转换通常在逻辑判断或者有逻辑运算符时被触发(|| && !)。

Boolean(2) // 显示类型转换 if(2) {} // 逻辑判断触发隐式类型转换 !!2 // 逻辑运算符触发隐式类型转换 2 || 'hello' // 逻辑运算符触发隐式类型转换

注意: 逻辑运算符(比如 || 和 &&)是在内部做了 boolean 类型转换,但实际上返回的是原始操作数的值,即使他们都不是 boolean 类型。

// 返回 number 类型 123,而不是 boolean 型 true // 'hello' 和 '123' 仍然在内部会转换成 boolean 型来计算表达式 let x = 'hello' && 123 // x === 123

boolean 类型转换只会有 true 或者 false 两种结果。

Boolean('') // false Boolean(0) // false Boolean(-0) // false Boolean(NaN) // false Boolean(null) // false Boolean(undefined) // false Boolean(false) // false

任何不在上面列表中的值都会转换为 true, 包括 object, function, Array, Date 等,Symbol 类型是真值,空对象和空数组也是真值。

Boolean({}) // true Boolean([]) // true Boolean(Symbol()) // true !!Symbol() // true Boolean(function() {}) // true

Number 类型转换

和 Boolean()、String() 方法一样, Number() 方法可以用来显式将值转换成 number 类型。
number 的隐式类型转换是比较复杂的,因为它可以在下面多种情况下被触发。

比较操作(>, <, <=, >=)

按位操作(| & ^ ~)

算数操作(- + * / %), 注意,当 + 操作存在任意的操作数是 string 类型时,不会触发 number 类型的隐式转换

一 元 + 操作

非严格相等操作(== 或者 !== ),注意,== 操作两个操作数都是 string 类型时,不会发生 number 类型的隐式转换

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f116d2ab68d2169acfe3429f815493f0.html