前端令人头疼的相等比较(js的==和===)

深入解析JavaScript中相等(==)与全等(===)运算符的区别,包括类型转换规则与比较流程,帮助理解变量比较背后的逻辑。

在JavaScript中有两种相等比较(相等==、全等===)

	1 === 1 //true
	1 === '1' //false
	'1' === 1 //false
	'1' === '1' //true

上面的结果没有疑问,但是如果是相等运算符(== )的话,那么全部都是true,因为==涉及了转换


“The comparison x == y, where x and y are values, produces true or false.”
(翻译:相等运算符用于比较两个值,返回true或false。)

规则如下(英文难看?下面有翻译,规则难懂?我总结了自己的,希望能帮上忙哈):

  • ReturnIfAbrupt(x).
  • ReturnIfAbrupt(y).
  • If Type(x) is the same as Type(y), then
  • Return the result of performing Strict Equality Comparison x === y.
  • If x is null and y is undefined, return true.
  • If x is undefined and y is null, return true.
  • If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  • If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  • If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  • If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  • If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x > * == ToPrimitive(y).
  • If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison > *ToPrimitive(x) == y.
    *Return false.

翻译:

  • 如果x不是正常值(比如抛出一个错误),中断执行。
  • 如果y不是正常值,中断执行。
  • 如果Type(x)与Type(y)相同,执行严格相等运算x === y。
  • 如果x是null,y是undefined,返回true。
  • 如果x是undefined,y是null,返回true。
  • 如果Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果。
  • 如果Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果。
  • 如果Type(x)是布尔值,返回ToNumber(x) == y的结果。
  • 如果Type(y)是布尔值,返回x == ToNumber(y)的结果。
  • 如果Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果。
  • 如果Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果。
  • 返回false。

我的理解
1. 比较的x和有一个不正常,就停止比较:(function(){console.log('我要抛错啦');throw new Error('123')})() == 1
2. x和y同类型就用===比较
3. x和y一个是null一个是undefined,返回true
4. 数字和字符串比较,字符串转换成数字,最终是两个数字的比较,如果转换出来的不是数字,可能是NaN,就false了
5. 如果有一个是布尔值,将布尔值转换成数字再继续比较,可能是true == '3'  到 1 == '3' 到 1 == 3 到 1 === 3 就是false啦
6. x和y一个是字符串、数字或Symbol,另一个是对象,对象先转换原始值,再比较
7. 不满足上面情况就是返回false

关于ToPrimitive

即将操作数转为原始类型的值.他也是规范中的抽象操作,同样可以翻译为等价的js代码,简单来说对于一个对象obj:

toPrimitive(obj)等价于:先计算obj.valueOf(),如果结果为原始值,则返回此结果;否则.计算obj.toString(),如果结果是原始值,则返回此结果;否则,抛出异常

作者:风起云帆
链接:https://www.jianshu.com/p/87a349434678


如果我说得不够清楚,可以看看前辈的。阮一峰 - 读懂 ECMAScript 规格

### 三、===== 运算符的核心区别 在 JavaScript 中,`==` `===` 是两种用于比较值的运算符,它们之间存在显著差异,特别是在类型处理比较逻辑方面。 - `==`(相等运算符)在比较两个值时会执行类型转换(即隐式转换),以确保两个操作数具有相同的类型后再进行比较。例如,当比较一个数字一个字符串时,JavaScript 会将字符串转换为数字,然后进行比较。这种行为可能导致一些非直观的结果,如 `0 == false` 返回 `true`,因为布尔值 `false` 被转换为了数字 `0` [^3]。 ```javascript console.log(5 == '5'); // true console.log(0 == false); // true console.log(null == undefined); // true ``` - `===`(严格相等运算符)则不会进行任何类型转换。它不仅比较值,还比较类型,只有当两个操作数的值类型都相等时才返回 `true`。因此,如果两个操作数的类型不同,则直接返回 `false`,这使得 `===` 更加可靠可预测 [^3]。 ```javascript console.log(5 === '5'); // false console.log(0 === false); // false console.log(null === undefined); // false ``` ### 四、类型转换规则 对于 `==` 运算符,其背后的类型转换规则较为复杂,涉及到多种情况下的转换逻辑。例如: - 当比较 `null` `undefined` 时,它们被视为相等 [^2]。 - 如果其中一个操作数是布尔值,则会将其转换为数字(`true` 转换为 `1`,`false` 转换为 `0`)再进行比较 [^3]。 - 如果一个操作数是字符串而另一个是数字,字符串会被转换为数字 [^3]。 - 如果一个是对象,另一个是数值或字符串,对象会被转换为基础类型的值(通过 `toString()` 或 `valueOf()` 方法)再进行比较 [^4]。 ### 五、性能与最佳实践 虽然 `==` 提供了灵活性,但由于其复杂的类型转换机制,可能会导致难以调试的问题。因此,在大多数情况下,推荐使用 `===` 来避免意外的类型转换,提高代码的可读性健壮性。 此外,从性能角度来看,`===` 通常比 `==` 更快,因为它不需要进行类型转换。尽管这种差异在大多数应用中微不足道,但在高性能要求的应用中可以考虑这一点 [^3]。 ### 六、特殊值的比较 某些特殊值之间的比较也体现了 `==` `===` 的不同行为: - `NaN` 与任何值(包括自身)使用 `==` 或 `===` 比较都会返回 `false`,这是因为 `NaN` 是唯一一个不等于自身的值。要检测 `NaN`,应使用 `isNaN()` 函数 [^3]。 - 对于对象引用,即使两个对象的内容完全相同,只要它们不是同一个对象的引用,`===` 就会返回 `false` [^4]。 ```javascript console.log(NaN == NaN); // false console.log(NaN === NaN); // false const obj1 = { key: "value" }; const obj2 = { key: "value" }; console.log(obj1 == obj2); // false console.log(obj1 === obj2); // false ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值