JavaScript 相等(==)和全等(===)运算符:你真的懂了吗?
大家好,这里是你们的前端小伙伴!今天咱们聊聊 JS 里最让人头秃的两个运算符:== 和 ===。别看它俩长得像,实际上一个是"老好人",一个是"铁面无私",一不小心就能把你带进屎山代码的深渊。下面咱们就用最接地气的方式,把这俩货讲明白!
== 和 === 到底有啥区别?
- ==(相等):会自动进行类型转换,只要值能对上号就算 true。
- ===(全等):类型和值都得一模一样,绝不含糊。
举个栗子:
1 == '1' // true,类型不同但值能转成一样
1 === '1' // false,类型不同直接 false
== 背后的"骚操作"——类型转换底层规则
== 运算符的类型转换其实有一套"祖传秘笈",官方叫"抽象相等比较算法"。简单来说,遇到不同类型时,它会按以下套路来"撮合":
- 类型一样,直接比值。
- null 和 undefined,这俩货==时永远 true。
- 字符串和数字,字符串转数字再比。
- 布尔值,先转成数字再比。
- 对象和原始类型,对象先调用 valueOf/toString 变成原始值。
来个表格,直观感受下:
| a | b | a == b | 说明 |
|---|---|---|---|
| null | undefined | true | 祖传兄弟 |
| '0' | 0 | true | 字符串转数字 |
| false | 0 | true | false 转 0 |
| [] | '' | true | [] -> '' |
| [] | 0 | true | [] -> '' -> 0 |
| [1] | 1 | true | [1] -> '1' -> 1 |
| [1,2] | '1,2' | true | [1,2] -> '1,2' |
| {} | '[object Object]' | false | 对象转字符串 |
是不是有点"真是栓Q"?一不小心就掉坑里。
类型转换流程
- 类型相同?直接比。
- null == undefined?true。
- 其中一个是 number?另一个转 number。
- 其中一个是 string?string 转 number。
- 其中一个是 boolean?boolean 转 number。
- 其中一个是对象?对象转原始值。
=== 的"铁面无私"
=== 就很简单粗暴,类型不一样直接 false,绝不含糊:
0 === false // false
'' === false // false
null === undefined // false
[] === false // false
Object.is:新时代的"较真哥"
ES6 新增了 Object.is,用来判断两个值是否"严格相等",但和 === 还是有点区别:
Object.is(NaN, NaN) // true,终于不是 false 了
Object.is(+0, -0) // false,=== 认为 true
Object.is(0, -0) // false
Object.is(1, 1) // true
一般开发用 === 就够了,Object.is 主要用在 polyfill 或底层库里。
深入剖析特殊值的比较
null 和 undefined
null == undefined // true
null === undefined // false
NaN
NaN == NaN // false
NaN === NaN // false
Object.is(NaN, NaN) // true
0、-0、+0
0 === -0 // true
Object.is(0, -0) // false
空字符串、false、0
'' == false // true
0 == '' // true
false == 0 // true
数组、对象和原始类型
[] == '' // true
[] == 0 // true
[1] == 1 // true
[1,2] == '1,2' // true
{} == '[object Object]' // false
真实开发中的"屎山"案例
-
表单校验
if (inputValue == null || inputValue == '') { // 以为能判断空,结果 0 也进来了 }这样不行啦!0 也会被当成"空",建议用 === 分开判断。
-
判断数组是否为空
if (arr == false) { // 空数组也进来了,真是离谱 }我们应该 arr.length === 0。
-
后端返回数据判断
if (data == undefined) { // null 也会进来 }这种情况就把它干掉,建议用 data === undefined。
-
布尔值判断
if (flag == true) { // flag 为 1 也会进来 }建议直接 if (flag) 或 if (flag === true)。
面试常考陷阱题
来,考考你:
-
[] == ![]结果是什么?为啥?- 答案:true。
- 解析:![] 为 false,[] == false,[] 转 '','' == false,'' 转 0,false 转 0,0 == 0,true。
-
null == 0结果?- 答案:false。
- 解析:null 只和 undefined 相等。
-
false == '0'结果?- 答案:true。
- 解析:'0' 转数字 0,false 转 0,0 == 0。
-
{} == '[object Object]'结果?- 答案:false。
- 解析:{} 转 '[object Object]',但类型不同,直接 false。
最佳实践和团队规范建议
- 能用 === 就别用 ==,团队代码规范直接禁用 ==。
- 判断 null/undefined 推荐 value == null,其他情况用 ===。
- 复杂类型比较用 lodash.isEqual 或 JSON.stringify。
- 不要用 == 判断布尔、数字、字符串混合类型。
- 面试遇到 == 相关题,先写出类型转换流程再答,别硬背。
总结
== 就像个"老好人",啥都想撮合一下,结果经常帮倒忙;=== 则是"铁面无私",只认死理。Object.is 更像"较真哥",连 NaN、+0、-0 都分得清清楚楚。开发时,咱们还是多用 ===,少踩坑,别让"屎山代码"毁了你的项目。
如果你觉得有用,记得点赞收藏,这期内容就到这里啦!下期见,拜拜~