JavaScript 中的类型相等性比较 (宽松比较的小问题)

JavaScript 中的类型相等性比较 (宽松比较的小问题)

在JavaScript中,比较两个值是否相等是一个常见的操作,但这个过程可能比你想象的要复杂。JavaScript 使用两种主要的相等性比较操作符: == (等于)和 === (严格等于)。这两种操作符在比较值时的行为有很大的不同,特别是在处理不同类型的值时。本文将详细探讨 JavaScript 中的类型相等性比较,包括特殊值(如 NaNundefinednull )的处理,以及原始值和对象之间的转换。

一、类型相等(==)与严格相等(===)

在 JavaScript 中, == 操作符被称为"等于"操作符,它在比较两个值时会进行类型转换。但如果两个值的类型相等(等同于严格模式 === 判断)

cobol 复制代码
console.log(1 == 1); // true

如果是复杂类型比较空间地址

cobol 复制代码
console.log({} == {}); // false

另一方面, === 操作符被称为"严格等于"操作符,它不会进行类型转换。如果两个值的类型不同, === 将直接返回 false

cobol 复制代码
console.log(1 === '1'); // false

二、特殊值的比较

JavaScript 中有几个特殊的值,它们在比较时有特殊的规则:

  • nullundefined 是两个特殊的值,它们在逻辑上被认为是相等的,但它们不等同于任何其他值:
cobol 复制代码
console.log(undefined == null); // true
console.log(undefined == false); // false
console.log(null == 0); // false
  • NaN (Not a Number)是一个特殊的值,用于表示不是一个数字的情况。 NaN 与任何值都不相等,包括它自己
复制代码
cobol 复制代码
console.log(NaN == NaN); // false
  • Symbol 是 ES6 中引入的一种新的原始数据类型,用于创建唯一的、不可变的值。两个 Symbol 值相等的条件是它们引用相同的 Symbol
cobol 复制代码
let sym1 = Symbol.for(1);
let sym2 = Symbol.for(1);
console.log(sym1 == sym2); // true

三、原始值之间的转换

在比较时,JavaScript 会尝试将原始值转换为数字,然后再进行比较。这种转换遵循特定的规则:

  • Booleantrue 转换为 1false 转换为 0
cobol 复制代码
console.log(false == 0); // true
  • Boolean 值也可以转换为 BigInt ,但这种转换在逻辑上并不直观,因此通常不推荐这样做:
cobol 复制代码
console.log(false == 0n); // false
  • Boolean 值也可以转换为字符串,但这种转换同样不直观:
cobol 复制代码
console.log(false == "0"); // false
  • 当比较 NumberString 时,字符串会尝试转换为 Number ,然后再进行比较
cobol 复制代码
console.log(10 == "10"); // true
console.log(10 == "10.0"); // true

四、对象转换为原始值

当使用 == 操作符比较对象时,JavaScript 会尝试将对象转换为原始值。这个过程首先尝试调用对象的 valueOf() 方法,如果返回的是一个基本类型,就使用这个值进行比较。如果 valueOf() 方法不存在或返回的不是基本类型,那么会尝试调用 toString() 方法。如果这两个方法都不存在或返回的不是基本类型,就会抛出 TypeError 异常。

例如:

复制代码
typescript 复制代码
const obj = {
  valueOf() {
    return {};
  },
  toString() {
    return "a string";
  },
};
 
console.log(obj == 1); //false

扩展:JS如何使判断式(a==1&&a==2&&a==3)成立

有时候,我们可能需要创建一个对象,使其在比较时能够返回不同的值。这可以通过在对象上定义 valueOf()toString() 方法来实现。下面是一个例子:

cobol 复制代码
const a = {
  counter: 1,
  valueOf() {
    const value = this.counter;
    this.counter++;
    return value;
  },
  toString() {
    return this.counter.toString();
  },
};
 
console.log(a == 1 && a == 2 && a == 3); // true

在这个例子中,对象 a 在第一次比较时返回 1 ,在第二次比较时返回 2 ,在第三次比较时返回 3 。这是因为 valueOf() 方法在每次调用时都会递增 counter 属性的值。

通过这篇文章,你应该对 JavaScript 中的类型相等性比较有了更深入的理解。记住, ===== 在比较时的行为有很大的不同,特别是在处理不同类型的值时。了解这些规则可以帮助你编写更可靠和可预测的代码。

相关推荐
OpenTiny社区2 分钟前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠31 分钟前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞35 分钟前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路1 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9491 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8681 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie1 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_1 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api
你听得到111 小时前
Flutter - 手搓一个日历组件,集成单日选择、日期范围选择、国际化、农历和节气显示
前端·flutter·架构
风清云淡_A1 小时前
【REACT18.x】CRA+TS+ANTD5.X封装自定义的hooks复用业务功能
前端·react.js