前端小知识003:JS中 == 与 === 的区别

在日常写 JavaScript 的过程中,===== 是两个经常会让开发者产生疑惑的比较运算符。它们看起来只差一个等号,但意义和行为却完全不同。理解这两者的区别,对于写出更加稳定、可靠的前端代码非常重要。


一、基础定义

==(宽松相等)

  • 会进行类型转换(type coercion)

  • 在比较前会尝试把两个值转换到同一类型再比较

  • 因此经常出现"看起来不合理但成立"的结果
    ===(严格相等)

  • 不会进行类型转换

  • 类型和值必须都相同才返回 true

  • 更加安全,推荐在大多数情况下使用

二、==的类型转换规则详解

2.1 字符串与数字的比较

当字符串与数字比较时,字符串会被转换为数字。

javascript 复制代码
console.log(123 == '123');     // true, '123' → 123
console.log(0 == '0');         // true, '0' → 0
console.log(1 == '1.00');      // true, '1.00' → 1
console.log(1 == '1abc');      // false, '1abc' → NaN
console.log(0 == '');          // true, '' → 0

2.2 布尔值与其他类型的比较

布尔值会先被转换为数字(true→1, false→0),然后再进行比较。

javascript 复制代码
console.log(true == 1);        // true, true → 1
console.log(false == 0);       // true, false → 0
console.log(true == '1');      // true, true → 1, '1' → 1
console.log(false == '');      // true, false → 0, '' → 0
console.log(true == '2');      // false, true → 1, '2' → 2

2.3 null 和 undefined 的特殊规则

nullundefined 在宽松相等中相互相等,但与其他值都不相等。

javascript 复制代码
console.log(null == undefined); // true
console.log(null == 0);        // false
console.log(null == '');       // false
console.log(undefined == 0);   // false
console.log(undefined == '');  // false

2.4 对象与原始值的比较

对象会通过 valueOf()toString() 方法转换为原始值后再比较。

javascript 复制代码
console.log([1] == 1);         // true, [1] → '1' → 1
console.log([1] == '1');       // true, [1] → '1'
console.log([] == 0);          // true, [] → '' → 0
console.log([] == false);      // true, [] → '' → 0, false → 0

const obj = {
  valueOf() { return 100; },
  toString() { return '200'; }
};
console.log(obj == 100);       // true, obj.valueOf() → 100

三、特殊情况分析

3.1 NaN 的异常行为

NaN与任何值(包括自己)都不相等。

javascript 复制代码
console.log(NaN == NaN);       // false
console.log(NaN === NaN);      // false
console.log(NaN == 0);         // false
console.log(NaN == 'NaN');     // false

// 判断 NaN 的正确方式
console.log(Number.isNaN(NaN)); // true
console.log(Object.is(NaN, NaN)); // true

3.2 复杂对象的比较

对象比较的是引用地址,而不是内容。

javascript 复制代码
const obj1 = { name: 'John' };
const obj2 = { name: 'John' };
const obj3 = obj1;

console.log(obj1 == obj2);     // false,不同引用
console.log(obj1 == obj3);     // true,相同引用
console.log(obj1 === obj2);    // false
console.log(obj1 === obj3);    // true

四、推荐使用===

javascript 复制代码
// 显式类型转换后使用 ===
const num = Number(inputValue);
if (num === 1) { ... }

// 使用 parseInt 明确转换
const page = parseInt(urlParams.page, 10);
if (page === 1) { ... }

// 使用 Boolean() 明确转换
const isValid = Boolean(someValue);
if (isValid === true) { ... }
相关推荐
全栈技术负责人2 小时前
拒绝“无法复现”:前端全链路日志排查实战手册
前端·全链路·问题排查思路
QT 小鲜肉2 小时前
【Linux常用命令大全】在 Linux 系统下 Git + Vim编辑器常用指令完全指南(亲测有效)
linux·开发语言·c++·笔记·git·编辑器·vim
b***9102 小时前
【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus
android·前端·后端·mybatis
G***E3162 小时前
前端路由懒加载实现,Vue Router与React Router
前端·vue.js·react.js
Jonathan Star2 小时前
前端需要做单元测试吗?哪些适合做?
前端·单元测试·状态模式
这儿有一堆花2 小时前
python视觉开发
开发语言·python
eason_fan2 小时前
解决 Monorepo 项目中 node-sass 安装失败的 Python 版本兼容性问题
前端·debug
q***73552 小时前
删除文件夹,被提示“需要来自 TrustedInstaller 的权限。。。”的解决方案
android·前端·后端
小满zs2 小时前
Next.js第八章(路由处理程序)
前端