JavaScript 数据类型与隐式转换详解
一、JavaScript 数据类型
JavaScript 是弱类型语言,变量类型由值决定,主要分为以下类型:
-
原始类型(Primitive Types):
number:数值(整数、浮点数、NaN、Infinity)。string:字符串(如"hello")。boolean:布尔值(true/false)。null:空值。undefined:未定义。symbol(ES6+):唯一且不可变的值。bigint(ES11+):大整数(如10n)。
-
引用类型(Reference Types):
object:对象(如{}、[]、Date、函数等)。
二、隐式转换规则
JavaScript 在运算或逻辑判断中会自动进行类型转换,遵循以下规则:
1. 转换为 boolean
- 假值(Falsy):
false、0、""(空字符串)、null、undefined、NaN。 - 真值(Truthy):其他所有值(包括
"0"、"false"、空数组[]、空对象{})。
if ("hello") {} // true(非空字符串)
if (0) {} // false
if ({}) {} // true(空对象是对象,存在即真)
2. 转换为 number
null→0undefined→NaNtrue→1,false→0- 字符串:空字符串
""→0,非数字字符串(如"123a")→NaN。
Number("42") // 42
Number("42abc") // NaN
Number(true) // 1
Number(null) // 0
3. 转换为 string
null→"null"undefined→"undefined"- 布尔值 →
"true"或"false"。 - 对象:调用
toString()方法(如[1,2].toString()→"1,2")。
String(42) // "42"
String(true) // "true"
String([1,2]) // "1,2"
三、隐式转换场景与示例
1. + 运算符
- 规则:优先拼接字符串,若操作数中有字符串,则转为字符串拼接。
- 示例:
console.log(1 + "2"); // "12"(数字转字符串拼接) console.log(1 + 2 + "3"); // "33"(先计算 1+2=3,再拼接 "3") console.log("3" + 4 + 5); // "345"(从左到右拼接)
2. -、*、/ 运算符
- 规则:优先转为数值运算。
- 示例:
console.log("5" - 2); // 3(字符串转数字) console.log("5" * "2"); // 10 console.log("abc" - 1); // NaN(无法转为数字)
3. == 宽松相等比较
- 规则:触发隐式转换,可能导致意外结果。
- 示例:
console.log(1 == "1"); // true(字符串转数字) console.log(0 == false); // true(布尔值转数字) console.log("" == 0); // true(空字符串转 0) console.log(null == undefined); // true(特殊规则) console.log([] == 0); // true(空数组转空字符串→转 0)
4. 对象参与运算
- 规则:对象先调用
valueOf(),若返回非原始值,再调用toString()。 - 示例:
let obj = { valueOf: () => 42, toString: () => "hello" }; console.log(obj + 1); // 43(优先调用 valueOf)let arr = [1, 2]; console.log(arr + 3); // "1,23"(数组转字符串 "1,2")
5. 条件判断中的转换
- 示例:
if (0) { /* 不执行 */ } // 0 → false if ("hello") { /* 执行 */ } // 非空字符串 → true if ([]) { /* 执行 */ } // 空数组是对象 → true
四、常见陷阱与规避方法
1. NaN 的传染性
console.log(5 + NaN); // NaN(任何与 NaN 的运算结果都是 NaN)
console.log(NaN === NaN) // false(NaN 是唯一不等于自身的值)
2. null 和 undefined 的特殊性
console.log(null == 0); // false(null 只与 undefined 宽松相等)
console.log(undefined + 1); // NaN
3. 推荐使用严格相等(===)
console.log(1 === "1"); // false(不触发类型转换)
console.log(0 === false); // false
4. 显式类型转换
// 转为数字
let num = +"42"; // 42
num = parseInt("42px"); // 42// 转为字符串
let str = 42 + ""; // "42"
str = String(42); // "42"// 转为布尔值
let bool = !!42; // true
五、总结
-
隐式转换规则:
+优先拼接字符串,其他运算符优先转为数字。- 对象通过
valueOf()和toString()转换为原始值。 - 宽松相等(
==)会触发复杂转换逻辑。
-
最佳实践:
- 使用
===代替==避免意外转换。 - 复杂运算时显式转换类型(如
Number()、String())。 - 注意
NaN、null、undefined的特殊行为。
- 使用
示例代码总结:
console.log(1 + "2"); // "12"
console.log("5" - 2); // 3
console.log([] == 0); // true(空数组 → "" → 0)
console.log({} + 1); // "[object Object]1"
console.log(Boolean("0")); // true(非空字符串为真)
