JavaScript: 数据类型的转换

作者 Lei Zhang 日期 2018-12-16
JavaScript: 数据类型的转换

(只记录易错转换)

一、 强制转换

1. Number()

(1) 原始类型值

// 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN

// 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN

// null:转成0
Number(null) // 0

与parseInt区别

parseInt('42 cats') // 42
Number('42 cats') // NaN

(2) 对象

Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组

Number({a: 1}) 		// NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5

之所以会这样,是因为Number背后的转换规则比较复杂。

第一步,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。

第二步,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。

第三步,如果toString方法返回的是对象,就报错。

var obj = {x: 1};
Number(obj) // NaN

// 等同于
if (typeof obj.valueOf() === 'object') {
Number(obj.toString());
} else {
Number(obj.valueOf());
}

默认情况下,对象的valueOf方法返回对象本身,所以一般总是会调用toString方法,而toString方法返回对象的类型字符串(比如[object Object])。所以,会有下面的结果。

Number({}) 			// NaN

2. String()

(1) 原始类型值

String(123) 		// "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"

(2) 对象

String({a: 1}) 		// "[object Object]"
String([1, 2, 3]) // "1,2,3"

String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。

  1. 先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
  2. 如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
  3. 如果valueOf方法返回的是对象,就报错。

3. Boolean()

它的转换规则相对简单:除了以下五个值的转换结果为false,其他的值全部为true

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

经测试,Boolean(false) == true

注意,所有对象(包括空对象)的转换结果都是true,甚至连false对应的布尔对象new Boolean(false)也是true

二、 自动转换

1. 不同类型的数据互相运算

123 + 'abc' 		// "123abc"

2. 对非布尔值类型的数据求布尔值

if ('abc') {
console.log('hello')
} // "hello"

3. 对非数值类型的值使用一元运算符(即+-

+ {foo: 'bar'} 		// NaN
- [1, 2, 3] // NaN

由于自动转换具有不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用BooleanNumberString函数进行显式转换。

参考文章: https://wangdoc.com/javascript/features/conversion.html