前言
拿到一个数据如果它不是我们想要的类型也不要慌乱,因为我们可以通过类型转换(通常是显式类型转换)人为把它转换成我们想要的类型。
但我们发现有时候即使没有人为使用代码进行转化,值的类型却悄悄变了,这是因为在某些代码场景下会发生隐式类型转换,JavaScript会自己悄咪咪改变值的类型。
你应该想到了,如果不对类型转换有深刻的了解在处理数据时我们会有多头疼,接下来让我们一起学习掌握它!
类型转换
显式类型转换
通过内置函数(如 String()
、Number()
、Boolean()
)主动转换类型。
String()
转换为字符串
String(null); // "null"
String(undefined); // "undefined"
String(true); // "true"
String(123); // "123"
String([1, 2, 3]); // "1,2,3"
String({a: 1}); // "[object Object]"
Number()
转换为数字
Number("123"); // 123
Number(" 123 "); // 123
Number("123abc"); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number([1]); // 1
Number([1, 2]); // NaN
Boolean()
转换为布尔值
Boolean(0); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean(false); // false
Boolean("0"); // true(非空字符串)
Boolean([]); // true(非空对象)
Boolean({}); // true
Boolean(function(){}); // true
隐式类型转换
在表达式运算、条件判断等场景中,JavaScript 引擎自动进行的类型转换。
显式转换和隐式转换只看当前的代码场景,原理是一样的,那么接下来学习一下类型转换的原理
类型转换的原理
1. 原始类型转原始类型
原始类型转数字
直接按照规定的转化规则转换
原始值 | 转换结果 |
---|---|
undefined | NaN |
null | 0 |
true / false | 1 / 0 |
"" (空字符串) | 0 |
"123" | 123 |
"123abc" | NaN |
" 123 " | 123 (自动去除空白) |
012 (前导零) | 12 (按十进制解析) |
0x12 (十六进制) | 18 (转为十进制) |
原始类型转字符串
直接按照规定的转化规则转换
原始值 | 转换结果 |
---|---|
undefined | "undefined" |
null | "null" |
true / false | "true" / "false" |
0 | "0" |
-0 | "0" |
NaN | "NaN" |
Infinity | "Infinity" |
字符串 | 直接返回 |
原始类型转布尔值
直接按照规定的转化规则转换
0 、-0 、NaN | false |
---|---|
"" (空字符串) | false |
null 、undefined | false |
false | false |
其他所有值 | true |
2. 引用类型转原始类型
引用类型转布尔
根据上面的规则我们可以知道引用类型转换为布尔都是true
引用类型转数值或字符串
当需要将引用类型转换为原始类型时,JavaScript引擎会自动调用ToPrimitive
方法,该方法根据转换的目标原始类型(String
或Number
)来决定转换过程。
ToPrimitive方法的转换步骤
- 判断对象是否为原始类型
- 如果对象已经是原始类型,直接返回。
- 调用对象的valueOf方法
- 如果对象不是原始类型,首先调用对象的
valueOf
方法。 - 如果
valueOf
方法返回的是原始类型,则直接返回该值。
- 调用对象的toString方法
- 如果
valueOf
方法返回的不是原始类型,或者没有定义valueOf
方法,则调用对象的toString
方法。 - 如果
toString
方法返回的是原始类型,则直接返回该值。
- 报错
- 如果
toString
方法返回的也不是原始类型,则抛出TypeError
错误。
如果目标原始类型为
string
则先执行第三步
valueOf()
valueOf()
是一个内置方法,在Object.prototype上,只有对象实例(new Number()
等构造函数创建的包装对象)能调用它,因为这些实例继承自Object
的原型链。
不同类型对象的返回值
- Array:返回数组对象本身。
- Boolean:返回布尔值true或false。
- Date:返回自1970年1月1日00:00:00 UTC以来的毫秒数。
- Function:返回函数本身。
- Number:返回数字值。
- Object:返回对象本身,这是默认情况。
- String:返回字符串值。
toString()
JavaScript中的toString()
方法也是一个内置函数中但不同的是大部分的构造函数原型上都重写了自己的toString 方法
以下是toString()
方法在不同数据类型上的应用:
- 对象
返回由'[object'和[[class]] '']'组成的字符串
const obj = { name: "John", age: 30 };
obj.toString(); // 输出:"[object Object]"
- 数组
返回由数组中每个值拼接而成的一个以逗号分隔的字符串
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.toString(); // 输出:"Banana,Orange,Apple,Mango"
- 布尔值 将布尔值转换为字符串"true"或"false"。
var bool = new Boolean(1);
var myvar = bool.toString(); // 输出:"true"
- 数字 将数字转换为指定进制的字符串。
const number = 10;
number.toString(2); // 输出:"1010"(二进制表示)
发生隐式类型转换的场景
1. 加法运算(+
)
若任一操作数是字符串,则将另一个转为字符串并拼接:
1 + "2"; // "12"
true + "abc"; // "trueabc"
否则,将操作数转为数字并相加:
1 + null; // 1(null 转为 0)
1 + undefined; // NaN(undefined 转为 NaN)
2. 其他算术运算(-
、*
、/
、%
)
将操作数转为数字:
"5" - 2; // 3
true * 3; // 3
"abc" / 2; // NaN
3. 宽松比较(==
)
若类型相同,直接比较值。
若类型不同,遵循以下规则:
null == undefined; // true(特殊规则)
"1" == 1; // true(字符串转为数字)
true == 1; // true(布尔转为数字)
[] == 0; // true(数组转为 0:[].toString() → "" → 0)
4. 条件判断
将值转为布尔类型:
if ("non-empty") { // true
// 执行代码
}
while (0) { // false(循环不执行)
// ...
}
练习题
console.log([]==![]);//分析为什么输出true?