运算符你真的会了吗?

前言

在JavaScript编程中,运算符是至关重要的元素之一。

它们允许开发人员执行各种操作,从简单的加法和减法到位运算和逻辑运算。

通过灵活使用这些运算符,我们能够更高效地处理数据和控制程序流程。

可是对于运算符的运行结果,你真的了如指掌吗?

本文将深入探讨JavaScript中常用的运算符,帮助读者加深对这门语言的理解并提升编程技能.

一元运算符

" + "是我们使用频率较高的运算符,一般用来数字的加法 (a+b) 或者数字的拼接 ('a'+'b') ,那如果我只有一个参数用来加法 (+a) ,那么运行结果是什么呢?这里我将带大家理解一元运算符 "+" 的运算规则。

一元运算符 "+" 会将 + 后面的参数转为数字

js 复制代码
 +'1' //Number(1)
 +[]//0
 +{} //NaN
+[1,2,3]//NaN

我们先来看看官方大大怎么说的:

一元加号运算符 (+) 将操作数转换为 Number 类型。

如果操作数不是原始值,则在应用一元加号运算符之前,先调用 ToPrimitive 抽象操作,该抽象操作根据传入的参数(标记为 hint)采取以下步骤之一:

  • 如果 hint 值为 "default",则首先尝试调用对象的 valueOf() 方法。如果返回原始值,则 JavaScript 尝试将其转换为 Number 类型。
  • 否则,如果 hint 值为 "string",则首先尝试调用对象的 toString() 方法。如果返回原始值,则 JavaScript 尝试将其转换为 Number 类型。

如果转换后的结果是 NaN,则一元加号表达式的结果为 NaN。否则,结果将是一个数字值,其符号与转换后的值相同。

ToPrimitive方法我在上一篇文章中有提到(纯干货!类型转换的前因后果)。

当操作数是数字类型时,一元运算符"+"不会对数字进行任何变化。它可以用来显式地将数字转换为正数,但实际上并不会改变数值本身

当操作数是非数字类型时,一元运算符"+"会尝试将其转换为数字类型。它会将字符串转换为相应的数字,如果无法转换,则返回NaN(Not a Number)

现在我们再来分析:

  1. + =>我们先进入 ToPrimitive ,数组无法让valueOf转为原始值,再调用toString方法,在上一篇文章中,我们提到,数组转为字符串会变成数组内元素加逗号的拼接,于是 就被转为空字符串,而空字符串转为数字 = 0.
  2. +{} =>同样的先进入 ToPrimitive,valueOf同样无法将对象转为原始值,再调用toString方法,对象调用toString会返回 "object object" ,然后再转为数字,而 "object object" 无法转为数字,于是转为NaN。

二元运算符

同样的,我们要讲的还是 "+",不过这里我们由加一个操作数变成了两个操作数相加。

js 复制代码
console.log([]+[]);//""
console.log([]+{});//"[object object]"

我们先看看官方文档是怎么描述的:

这 加法运算符可以执行字符串连接,也可以执行数值 加法。

这 生产 AdditiveExpression:AdditiveExpression MultiplicativeExpression 的计算结果如下: +

  1. 设 lref 是计算 AdditiveExpression 的结果。

  2. 设 lval 为 GetValue(lref)。

  3. 设 rref 是计算 MultiplicativeExpression 的结果。

  4. 设 rval 为 GetValue(rref)。

  5. 设 lprim 为 ToPrimitive(lval)。

  6. 设 rprim 为 ToPrimitive(rval)。

. 如果 Type(lprim ) 为 String 或 Type(rprim) 为 String,则

  1. 返回 连接 ToString(lprim ) 的结果的 String 后跟 ToString(rprim)

  2. 返回 将加法运算应用于 ToNumber(lprim ) 的结果 和 ToNumber(rprim)

简单的来说:

1.当加号两边有一个是字符串,则按字符串进行拼接

2.否则,转到 number 进行计算

我们再回到一开始的代码块

js 复制代码
console.log([]+[]);//""
console.log([]+{});//"[object object]"
  1. \[\]+\[\],左右两边没有字符串,于是分别转为Number进行计算,先调用valueOf,无果,再调用toString,左右两边都转成空字符串,可以开始拼接,于是计算结果就是""
  2. \[\]+{},同样的,左右两边没有字符串,于是又转为Number计算,\[\]转为空字符串,而{}会转为"object object",所以拼接后的结果就是"object object"

== 运算符

同样,先来看看官方文档:

这 比较 x == y , 其中 x 和 y 是值,产生 true 或 false。这样的比较 按如下方式执行:

  1. 如果 Type(x ) 与 Type(y) 相同,则

    1. 如果 Type(x ) 为 Undefined,则返回 true。

    2. 如果 Type(x ) 为 Null,则返回 true。

    3. 如果 Type(x) 为 Number,则

      1. 如果 x 为 NaN ,则返回 false。
      2. 如果 y 为 NaN ,则返回 false。
      3. 如果 x 与 y 的 Number 值相同,则返回 true。
      4. 如果 x 为 + 0 且 y 为 −****0 , 返回 true。
      5. 如果 x 为 − 0 且 y 为 +0 ,则返回 true。****
      6. 返回 false。
    4. 如果 Type(x ) 为 String,则如果 x 和 y 是完全相同的字符序列(长度相同),则返回 true 和相应位置的相同字符)。否则,返回 false。

    5. 如果 Type(x ) 为布尔值,则如果 x 和 y 均为 true 或均为 false ,则返回 true 。否则,返回 false。

    6. 如果 x 和 y 引用同一对象,则返回 true 。 否则,返回 false。

  2. 如果 x 为 null 且 y 未定义 ,则返回 true。

  3. 如果 x 未定义 且 y 为 null ,则返回 true。

  4. 如果 Type(x ) 为 Number,Type(y ) 为 String,

    则返回 比较结果 x == ToNumber(y)。

  5. 如果 Type(x ) 为 String 且 Type(y ) 为 Number,

    则返回 比较结果 ToNumber(x ) == y。

  6. 如果 Type(x ) 为 Boolean,则返回比较结果 ToNumber(x ) == y。

  7. 如果 Type(y ) 为 Boolean,则返回比较结果 x == ToNumber(y)。

  8. 如果 Type(x ) 为 String 或 Number,并且 Type(y ) 为 Object,

    返回比较结果 x == ToPrimitive(y)。

  9. 如果 Type(x ) 是 Object 且 Type(y ) 是 String 或 Number,

    返回比较结果 ToPrimitive(x ) == y。

  10. 返回 false。

看完这段官方文档,掘友们头都大了...

让我帮大家总结一下:

简单地说就是将左右两边都转换成数字比较,并且转换完毕以后,只要有一个为NaN就是false

举个例子:

js 复制代码
console.log(false == []);//true

左边false转为数字是0,右边 先调用valueOf,转不了,再调用toString变成空字符串,再转为Number为0,于是乎返回true。

掘友们看到这里,会感觉好像运算符都差不多,都是按照基本相同的规则进行运算的。没错!就是将操作数进行转换然后再操作。如果有不清楚类型转换的掘友可以移步我的上一篇文章(纯干货!类型转换的前因后果)。

结尾

掘友们学习完本文,就可以出去跟别人说:运算符,我真的会了!(我们这里讲的运算符)。轻轻松松拿捏。

相关推荐
陈随易15 分钟前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
恋猫de小郭1 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter
严肃小白兔2 小时前
TanStack Router 更新构建工具链:Node.js 兼容性、路由分割与前端工程实践
前端·node.js·状态模式
IT_陈寒2 小时前
Vue这个奇葩的响应式问题让我加班到凌晨
前端·人工智能·后端
风骏时光牛马2 小时前
功能可用性自动化测试验证
前端
爱敲代码的小黄10 小时前
神经网络入门指南:从 CNN、RNN 到 Attention
人工智能·面试·程序员
LucianaiB12 小时前
【元宝搜索开发者征文大赛】AI时代,学得慢就不用学?用元宝搜索打造一个教程保质期,确保每一个教程符合你的现状
前端·人工智能·ai编程
excel12 小时前
JavaScript 对象池:减少高频对象创建与 GC 压力
前端
陈随易14 小时前
纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS
前端·后端·程序员
子兮曰15 小时前
Chrome 权限元素实战:144 与 151 的渐进增强写法
前端·javascript·chrome