前言
Javascript 是一种弱类型语言,这意味着变量是没有明确类型的,而是由 JavaScript 引擎在编译时隐式完成。类型转换就是将一种数据类型转换为另一种数据类型,例如:
20 + "twenty" // "20twenty"
"10" * "10" // 100
2 - "x"
Javascript 使用严格相等(===)和宽松相等(==)来测试两个值的相等性,类型转换仅在使用宽松相等运算符时发生。当使用 === 测试严格相等时,要比较的变量的类型和值都必须相同,例如:
10 === 10 // true
NaN === NaN // false
在上面的代码中,10 和 10 都是数字并且是完全相等的,所以正如预期的那样返回了true
,两个 NaN 永远不会相等。当使用 == 测试宽松相等时,可能会发生隐式转换:
'20' == 20 // true
false == 0 // true
对于任何数据类型,无论是原始类型还是对象,都可以进行类型转换。尽管原始类型和对象的转换逻辑各不相同,但是都只能转换为三种类型:字符串(string)、数字(number)、布尔值(boolean) 。
JavaScript 中的类型转换有两种方式:
-
隐式类型转换: 由 JavaScript 编译器完成的自动类型转换。
-
显式类型转换: 由开发人员完成的手动类型转换。
下面先来看看 JavaScript 中的显式和隐式类型转换。
一. 显示类型转换
我们可以通过 JavaScript 内置的一些 API 将一种类型转换为另一种类型,这称为显式类型转化。执行显式类型转换的最简单方法是使用 Boolean()
、Number()
和 String()
、parseInt()
等函数,例如:
String(2 - true); // '1'
'56' === String(56); // true
Number('2350e-2'); // '23.5'
Number('23') + 7; // 30
Boolean(''); // false
Boolean(2) === true; //true
二. 隐式类型转换
隐式类型转换是将一种数据类型转换为另一种数据类型(确保在相同数据类型之间完成操作)以使运算符或函数正常工作,这种转换是由 JavaScript 编译器自动完成的,隐式类型转换也称为类型强制。例如:
'25' + 15; // '2515'
23 * '2'; // 46
23 - true; // 22
true - null; // 1
false + undefined; // NaN
const arr = [];
if(arr) { console.log('Hello World') };
下面这些常见的操作会触发隐式地类型转换,编写代码时要格外注意:
-
运算相关的操作符:+、-、+=、++、* 、/、%、<<、& 等。
-
数据比较相关的操作符: >、<、== 、<=、>=、===。
-
逻辑判断相关的操作符: &&、!、||、三目运算符。
1. + 运算符
/* 一个操作数 */
+ x // 将x转化为数字, 如果不能转化为数组将输出NaN
+ "1234string" // NaN
+ 1 // 1
+ '1' // 1
+ true // 1
+ undefined // NaN
+ null // 0
+ new Date() // 1660493819396
/* 两个操作数 */
a + b
// 1. 如果其中任何一个是对象,则先将其转换为原始类型
{} + {} // '[object Object][object Object]'
[] + [] // ''
[] + new Date() // 'Mon Aug 15 2022 00:18:18 GMT+0800 (中国标准时间)'
// 2. 如果一个是字符串,则将另一个转换为字符串
1 + '' // '1'
'' + 1 // '1'
'' + true // 'true'
// 3. 否则,将两者都转换为数字
1 + true // 2
true + true // 2
2. -、*、/、++、--
// 将一个或多个值转换为数字
- '1' // -1
[] - 1 // -1
[] - {} // NaN
3. ==、!=
// 两个操作数
a == b
// 1. 如果一个是 `null` 而另一个是 `undefined`,它们是相等的
null == undefined // true
// 2. 如果一个是数字,另一个是字符串,将字符串转换为数字,再比较
1 == '1' // true
// 3. 如果其中一个是布尔值,将其转换为数字,再次比较
true == 1 // true
false == 0 // true
// 4. 如果一个是对象,另一个是数字或字符串,将对象转换为原始类型,再次比较
[1] == 1 // true
['1'] == '1' // true
下图是在使用 == 时,判断两个操作数是否相等的总结(绿色表示相等,白色表示不等):
4. >、>=、<、<=
// 两个操作数
a > b
// 1. 如果其中一个是对象,则将其转换为原始类型,再次比较
[2] > 1 // true
// 2. 如果两者都是字符串,使用字母顺序比较它们
'b' > 'a' // true
// 3. 如果其中一个是数字,则将一个或两个非数字转换为数字
'2' > 1 // true
5. in
/* 如果左操作数不是字符串,则将其转换为字符串 */
a in b
'1' in {1: ''} // true
1 in {1: 'a'} // true
1 in ['a', 'b'] // true