【JavaScript】day19-type-conversion

作者:mario 发布时间: 2026-08-20 阅读量:6 评论数:0

第十九天:类型转换与比较 — JS 中最容易踩坑的地方

蜗牛往上爬 · 前端工业可视化学习笔记 第 19 篇
昨天学了变量和六大数据类型,今天深入 JS 最"坑"的两块:类型转换和比较运算。"5" + 3 等于 "53""5" - 3 等于 2===== 到底有什么区别?把这些搞清楚,能避免 80% 的 JS 初级 bug。


目录


一、显式类型转换

显式转换 = 你主动调用函数去转换类型。

转为字符串

console.log(String(123));       // "123"
console.log(String(true));      // "true"
console.log(String(null));      // "null"
console.log(String(undefined)); // "undefined"
console.log((123).toString());  // "123"

转为数字

// Number():严格转换,失败返回 NaN
console.log(Number("123"));      // 123
console.log(Number("123.45"));   // 123.45
console.log(Number("abc"));      // NaN(转换失败)
console.log(Number(""));         // 0(空字符串 → 0)
console.log(Number(true));       // 1
console.log(Number(false));      // 0
console.log(Number(null));       // 0
console.log(Number(undefined));  // NaN

// parseInt():解析整数,遇到非数字就停
console.log(parseInt("123abc"));  // 123
console.log(parseInt("abc123"));  // NaN(开头不是数字)
console.log(parseInt("3.14"));    // 3(只取整数部分)

// parseFloat():解析浮点数
console.log(parseFloat("3.14"));  // 3.14
console.log(parseFloat("3.14.15")); // 3.14(遇到第二个小数点就停)

转为布尔

console.log(Boolean(1));          // true
console.log(Boolean(0));          // false
console.log(Boolean("hello"));    // true
console.log(Boolean(""));         // false
console.log(Boolean(null));       // false
console.log(Boolean(undefined));  // false
console.log(Boolean(NaN));        // false

二、隐式类型转换

隐式转换 = JS 引擎在你不知情的情况下自动转换类型。这是很多 bug 的来源。

字符串拼接 → 转字符串

console.log("5" + 3);        // "53"(数字 3 被转为字符串)
console.log("温度:" + 65);   // "温度:65"
console.log(1 + "2" + 3);    // "123"(从左到右,1+"2"→"12","12"+3→"123")

算术运算 → 转数字

console.log("5" - 3);        // 2(字符串 "5" 被转为数字)
console.log("6" * "2");      // 12
console.log("10" / "2");     // 5
console.log("hello" - 1);    // NaN("hello" 无法转为数字)

逻辑判断 → 转布尔

if ("hello") {               // 非空字符串 → true
  console.log("执行了");
}

if (0) {                     // 0 → false
  console.log("不会执行");
}

三、Falsy 值:6 个"假"值

只有以下 6 个值转为布尔是 false,其余全部true

Falsy 值

说明

false

布尔假

0 / -0

数字零

"" / ''

空字符串

null

空值

undefined

未定义

NaN

非数值

容易搞错的 Truthy 值

console.log(Boolean(" "));    // true(空格字符串 ≠ 空字符串)
console.log(Boolean([]));     // true(空数组)
console.log(Boolean({}));     // true(空对象)
console.log(Boolean("0"));    // true(字符串 "0" ≠ 数字 0)
console.log(Boolean("false")); // true(非空字符串)

记忆口诀:“0 空 null 假 NaN undefined” —— 6 个 falsy,其余全 truthy。


四、== 与 === 的区别

这是 JS 面试必考题,也是日常开发中最容易踩坑的地方。

== 宽松相等(会做类型转换)

console.log(5 == "5");           // true("5" 转成 5)
console.log(0 == false);         // true(false 转成 0)
console.log("" == false);        // true(都转成 0)
console.log(null == undefined);  // true(特殊规则)
console.log([1] == 1);           // true([1] 转成 "1" 再转成 1)

=== 严格相等(不做类型转换)

console.log(5 === "5");           // false(类型不同)
console.log(0 === false);         // false(类型不同)
console.log("" === false);        // false(类型不同)
console.log(null === undefined);  // false(类型不同)

一句话总结

==  先转换类型,再比较值    → 不可预测,容易出 bug
=== 不转换类型,直接比较     → 可预测,推荐使用

规则:永远用 ===,除非你明确知道自己在做什么

NaN 的特殊性

console.log(NaN === NaN);  // false!NaN 不等于任何值,包括自己
// 判断 NaN 用 isNaN() 或 Number.isNaN()
console.log(isNaN(NaN));         // true
console.log(Number.isNaN(NaN));  // true(ES6,更严格)

五、比较运算符

console.log(5 > 3);     // true
console.log(5 >= 5);    // true
console.log(3 < 5);     // true
console.log(5 <= 5);    // true
console.log(5 !== "5"); // true(严格不等于)
console.log(5 != "5");  // false(宽松不等于,会做类型转换)

六、逻辑运算符与短路求值

基本用法

// && 与(两边都为 true 才为 true)
console.log(true && true);    // true
console.log(true && false);   // false
console.log(5 > 3 && 2 < 4);  // true

// || 或(任意一边为 true 就为 true)
console.log(true || false);   // true
console.log(false || false);  // false

// ! 非(取反)
console.log(!true);            // false
console.log(!(5 > 3));         // false
console.log(!!"hello");        // true(双重否定 → 转布尔)
console.log(!!"");             // false

短路求值(重要!)

// &&:左边为 false,右边不执行
false && console.log("不会执行");
0 && console.log("也不会执行");

// ||:左边为 true,右边不执行
true || console.log("不会执行");
"hello" || console.log("也不会执行");

// 实战用法:设置默认值
var deviceName = userInput || "默认设备名";
// 如果 userInput 是 falsy,就取 "默认设备名"

// 实战用法:安全访问
var result = obj && obj.data && obj.data.value;
// 如果 obj 或 obj.data 不存在,不会报错,返回 undefined

七、动手练:运算符 15 题

// 1. "10" + 20 的结果?为什么?
// 2. "10" - 5 的结果?为什么?
// 3. 0 == false 和 0 === false 的结果?
// 4. null == undefined 和 null === undefined 的结果?
// 5. typeof NaN 的结果?
// 6. NaN === NaN 的结果?
// 7. 写出以下值的 Boolean() 结果:0, "", " ", [], {}, null, undefined, NaN
// 8. "5" * "3" 和 "5" + "3" 的结果?
// 9. !!"hello" 和 !!"" 的结果?
// 10. 变量 temp = 85,写表达式判断 temp 是否在 60-80 之间
// 11. 用 || 给变量设置默认值
// 12. 3 > 2 > 1 的结果?(提示:从左到右执行)
// 13. Number("123abc")、Number("")、Number("  ")、Number(null)、Number(undefined)
// 14. parseInt("3.14") 和 parseFloat("3.14") 的结果?
// 15. 写表达式:温度(temp)大于80 且 状态(status)是"运行中"

八、常见坑点与最佳实践

坑点 1:+ 运算符的二义性

// 加法有两个含义:数字相加 和 字符串拼接
// 只要有一个操作数是字符串,+ 就是拼接
console.log(1 + 2 + "3");  // "33"(先 1+2=3,再 "3"+"3"="33")
console.log("1" + 2 + 3);  // "123"(先 "1"+2="12",再 "12"+3="123")

坑点 2:== 的隐式转换链

console.log(false == "0");  // true
console.log(false == 0);    // true
console.log("" == 0);       // true
// 这就是为什么永远用 === !

坑点 3:typeof 的局限性

console.log(typeof null);        // "object" ← bug
console.log(typeof [1, 2, 3]);   // "object" ← 无法区分数组和对象
console.log(typeof NaN);         // "number" ← NaN 是 number 类型

最佳实践

// 1. 永远用 === 和 !==,不用 == 和 !=
// 2. 判断 NaN 用 isNaN() 或 Number.isNaN()
// 3. 判断数组用 Array.isArray()
// 4. 变量赋值前做类型检查
// 5. 用 !! 快速转布尔

九、总结

今天学了什么

关键点

显式转换

Number() / String() / Boolean() / parseInt() / parseFloat()

隐式转换

+ 优先拼接,-*/ 优先转数字

Falsy 值

6 个:false / 0 / “” / null / undefined / NaN

== vs ===

== 会类型转换,=== 不会。永远用 ===

逻辑运算符

&&(与)、

NaN

不等于任何值,用 isNaN() 判断

🎯 类型转换和比较是 JS 最容易出 bug 的地方。记住铁律:永远用 ===,显式转换代替隐式转换。下周进入流程控制:if/else 和循环。

评论