js面试系列: `==`和 `===`的区别

前言

春招在即,时间十分可贵,今天本人继续带大家来探秘js系列的考题,之前我们已经讲过了js考题中的类型转换机制,现在让我们来探索js中的等值操作符吧。

等值操作符

==(等于操作符)

等值操作符是我们经常会使用的等值比较方法,我们都是用(==)两个等号来进行表示的,如果等号两边的数相等的话,就会返回true

在之前的文章js的类型转换机制中,我们已经介绍过JavaScript中存在着隐式转换机制。当我们使用等于操作符(==)时,在比较过程中,就会进行类型转换,再来确定值是否相等。 如:

js 复制代码
let a = (true == 1) //true
let b = ("2" == 2) //true
let c = (null == undifined) //true

但是等于操作符在遇到与引用类型相关的类型转换时,会有所不同。在将引用类型转换为原始值时,JavaScript 会调用对象的 valueOf()toString() 方法,以便获取一个原始值。这两个方法的返回值会根据需要进行转换。JavaScript 引擎首先尝试调用对象的 valueOf() 方法,如果返回的值不是原始值(即对象),则继续尝试调用 toString() 方法。如果 toString() 方法返回的值是原始值,则使用该值进行比较。

下面是具体的转换过程:

  1. 如果对象具有 valueOf() 方法且返回的值是原始值(非对象),则直接使用该值进行比较。
  2. 如果对象没有 valueOf() 方法,或者 valueOf() 返回的是对象,那么 JavaScript 将调用对象的 toString() 方法。
  3. 如果对象具有 toString() 方法且返回的值是原始值(非对象),则直接使用该值进行比较。
  4. 如果对象没有 toString() 方法,或者 toString() 返回的是对象,则会抛出 TypeError 错误。

注意: valueOf() 只能将包装类的对象转换为原始类型

[] == ![]

在面试中,[] == ![] 也是一个十分常考的点,它也与上面的等值操作中的引用类型转换相关。 现在来解释 [] == ![] 是如何进行判断的:

  1. 首先,![] 运算符 ! 是逻辑非操作符,它会将其操作数转换为Boolean类型,然后取其相反值。由于 [] 是一个非空的数组,转换为Boolean类型后为 true,所以 ![] 的值为 false
  2. 然后,根据运算符优先级,==! 优先级高,所以 ![] 会先计算出结果 false
  3. 接着,[]false 进行比较。根据相等运算符的规则,在进行比较之前,JavaScript 会尝试将两个值转换为相同的类型。因为 [] 是一个对象(数组),而 false 是一个布尔值,所以 JavaScript 会将 [] 转换为一个原始值。
  4. 数组 [] 转换为原始值时会调用其 toString() 方法,将其转换为一个空字符串 ""。然后,空字符串 "" 转换为数字时会变成 0
  5. 所以最终的比较变成了 0 == false
  6. 在比较过程中,布尔值 false 会被转换为数字 0。因此,这个比较最终变成了 0 == 0
  7. 最终结果是 true

注意: 任何引用类型转boolean都是true

===(恒等操作符)

在JavaScript中恒等操作符也称为(### 严格相等运算符)由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同。如:

js 复制代码
let a = (true === 1) //false
let b = ("2" === 2) //false
let c = (null === undifined) //false

从以上示例中,我们可以看出,=== 恒等操作符,在比较两边的两个值时,会比较两个值是否严格相等,不会进行类型转换。只有在两个值的类型相同且值也相等的情况下,才会返回 true

区别

  1. 类型转换: == 运算符会进行类型转换,而 === 运算符不会进行类型转换。
  2. 比较结果: == 运算符在某些情况下会产生不直观的比较结果,而 === 运算符始终提供更严格的比较。

总结

  • 相等操作符 ==

    • 使用两个等号 == 进行比较时,会进行类型转换,然后再比较值是否相等。
    • 在比较过程中,引用类型会先尝试调用 valueOf() 方法,然后再调用 toString() 方法,将其转换为原始值进行比较。
    • 示例:[] == ![],在比较过程中,数组会被转换为空字符串,然后再转换为数字 0,最终比较结果为 0 == 0,返回 true
  • 严格相等操作符 ===

    • 使用三个等号 === 进行比较时,不会进行类型转换,严格比较两个值的类型和值是否完全相同。
    • 只有在类型和值都相同的情况下才会返回 true
    • 示例:true === 1,因为类型不同,返回 false

综上所述,=== 运算符通常更安全,因为它可以避免因类型转换而导致的意外行为。因此,在可能的情况下,推荐使用 === 运算符进行比较。

相关推荐
Martin -Tang13 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发14 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html