开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
一、概述
JS
中有六种简单数据类型:undefined
、null
、boolean
、string
、number
、symbol
,以及引用类型: object
但是我们在声明的时候只有一种数据类型,到运行期间才会确定当前类型
let a = b ? b : 0
上面的代码, a
的值在编译阶段是无法获取的,只有等到程序运行时才能知道
虽然变量的类型是不确定的,但是各个运算符对数据是有要求的,如果运算中的类型与预期不符合,就会发生类型转换机制
常见的类型转换有:
- 强制转换(显式转换)
- 自动转换(隐式转换)
显式类型转换
显式转换,顾名思义就是我们很清楚的看到类型的转变,常见的方法有:
- Number()
- parseInt()
- String()
- Boolean()
Number()
将任意类型的值转为数字类型
转换规则:
初始值 | 转换结果 |
---|---|
undefined | NaN |
null | 0 |
true | 1 |
false | 0 |
string | 根据语法和转换规则来转换 |
Symbol | Throw a TypeError exception |
Object | 先调用toPrimitive,在调用toNumber |
实践一下:
function log(arg) {
console.log(arg);
}
log(Number(undefined)); // NaN
log(Number(null)); // 0
// boolean
log(Number(true)); // 1
log(Number(false)); // 0
// string 只要包含一个非数字则转换成NaN
log(Number("abc123")); // NaN
log(Number("123abc")); // NaN
log(Number("abc")); // NaN
log(Number("123")); // 123
log(Number("")); // 0
// object 通常转换成NaN 除了单个数字的数组
log(Number([1, 2, 3])); // NaN
log(Number([100])); // 100
log(Number(["100"])); // 100
log(Number({ a: 1 })); // NaN
从上面可以看出,转换object
的时候一般只有一个元素是可以转换为Number
类型,其他的转为NaN
,字符串只要包含一个非数字的,整个字符串就会被转为NaN
parseInnt()
parseInt()
相比Number()
要稍微宽松一些,parseInt()
函数逐个解析字符,遇到不能转换的就停下来
function log(arg) {
console.log(arg);
}
log(parseInt(undefined)); // NaN
log(parseInt(null)); // NaN
// boolean
log(parseInt(true)); // NaN
log(parseInt(false)); // NaN
// string 遇到不能转换的则停下来
log(parseInt("abc123")); // NaN
log(parseInt("123abc")); // 123
log(parseInt("abc")); // NaN
log(parseInt("123")); // 123
log(parseInt("")); // NaN
// object 遇到不能转换的就停止转换
log(parseInt([1, 2, 3])); // 1
log(parseInt([100])); // 100
log(parseInt(["100"])); // 100
log(parseInt({ a: 1 })); // NaN
String()
可以将任意类型的值转化成字符串
转换规则:
初始值 | 转换结果 |
---|---|
undefined | 'undefined' |
null | 'null' |
boolean | 'true' or 'false' |
number | number |
Symbol | Throw a TypeError exception |
Object | 先调用toPrimitive,在调用toString |
实践一下:
function log(arg) {
console.log(arg);
}
log(String(undefined)); // 'undefined'
log(String(null)); // 'null'
// boolean
log(String(true)); // 'true'
log(String(false)); // 'false'
// number
log(String(123)); // '123'
// object
log(String([1, 2, 3])); // '1,2,3'
log(String([100])); // '100'
log(String(["100"])); // '100'
log(String({ a: 1 })); // '[object object]'
需要注意的是数组的转换
Boolean()
可以将任意类型转为布尔类型,转化规则如下:
初始值 | 转换为 true 的值 | 转换为 false 的值 |
---|---|---|
undefined | 转换为false | |
null | 转换为false | |
number | 非0数值 | 0和NaN |
string | 非空字符串 | ''(空字符串) |
object | 任意对象 | null |
实践一下:
function log(arg) {
console.log(arg);
}
log(Boolean(undefined)); // false
log(Boolean(null)); // false
// string
log(Boolean("")); // false
log(Boolean("a")); // true
log(Boolean("0")); // true
// number
log(Boolean(0)); // flase
log(Boolean(NaN)); // flase
log(Boolean(100)); // true
// object
log(Boolean([1, 2, 3])); // true
log(Boolean([])); // true
log(Boolean({ a: 1 })); // true
log(Boolean({})); // true
三、隐式转换
当运算符两边的操作数不是同一类型的时候,有两种
情况会发生隐式转换:
- 比较运算(
==
、!=
、>
、<
)、if
、while
需要布尔值的地方 - 算术运算 (
+
、-
、*
、/
、$
)
隐式转换布尔值
以下几种情况会被隐式转换成 false
- undefined
- null
- false
- +0
- 0
- -0
- NaN
- ""
除了上面的几种会被转化成false
,其他都被转换成true
自动转换成字符串
预期为字符串的地方,就会将非字符串的值自动转换为字符串
具体规则:先将符合类型的值转为原始类型的值,再将原始类型的值转为字符串
常发生在+
运算中,一旦存在字符串,则会进行字符串拼接
function log(arg) {
console.log(arg);
}
log("8" + false); // 8false
log("8" + true); // 8true
log("8" + undefined); // 8undefined
log("8" + null); // 8null
log("8" + "a"); // 8a
log("8" + []); // 8
log("8" + [1, 2, 3]); // 81,2,3
log("8" + {}); // 8[object Object]
log("8" + { a: 1 }); // 8[object Object]
log("8" + function () {}); // 8function () {}
自动转换成字符串
除了 +
有可能把运算转为字符串,其他运算符都会把运算自动转为数值
function log(arg) {
console.log(arg);
}
log("8" - true); // 7
log("8" - "2"); // 6
log("8" * 2); // 16
log(8 + null); // 8
log(8 + undefined); // NaN
log(8 * []); // 0
log(8 * [1, 2, 3]); // NaN
log(8 * {}); // NaN
log(8 * { a: 1 }); // NaN
log("abc" - 1); // NaN
log(false / "8"); // 0
null
转为数值的时候,值为0
,undefined
转为数值的时候,值为 NaN
, 不为空的数组也会转为NaN