前言
在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)
现在我们再来分析:
- +[ ] =>我们先进入
ToPrimitive
,数组无法让valueOf转为原始值,再调用toString方法,在上一篇文章中,我们提到,数组转为字符串会变成数组内元素加逗号的拼接,于是[ ] 就被转为空字符串,而空字符串转为数字 = 0. - +{} =>同样的先进入
ToPrimitive
,valueOf同样无法将对象转为原始值,再调用toString方法,对象调用toString会返回 "[object object]" ,然后再转为数字,而 "[object object]" 无法转为数字,于是转为NaN。
二元运算符
同样的,我们要讲的还是 "+",不过这里我们由加一个操作数变成了两个操作数相加。
js
console.log([]+[]);//""
console.log([]+{});//"[object object]"
我们先看看官方文档是怎么描述的:
这 加法运算符可以执行字符串连接,也可以执行数值 加法。
这 生产 AdditiveExpression:AdditiveExpression MultiplicativeExpression 的计算结果如下:
+
设 lref 是计算 AdditiveExpression 的结果。
设 lval 为 GetValue(lref)。
设 rref 是计算 MultiplicativeExpression 的结果。
设 rval 为 GetValue(rref)。
设 lprim 为 ToPrimitive(lval)。
设 rprim 为 ToPrimitive(rval)。
简单的来说:
1.当加号两边有一个是字符串,则按字符串进行拼接
2.否则,转到 number 进行计算
我们再回到一开始的代码块
js
console.log([]+[]);//""
console.log([]+{});//"[object object]"
-
\]+\[\],左右两边没有字符串,于是分别转为Number进行计算,先调用valueOf,无果,再调用toString,左右两边都转成空字符串,可以开始拼接,于是计算结果就是""
== 运算符
同样,先来看看官方文档:
这 比较 x == y , 其中 x 和 y 是值,产生 true 或 false。这样的比较 按如下方式执行:
如果 Type(x ) 为 Undefined,则返回 true。
如果 Type(x ) 为 Null,则返回 true。
如果 Type(x) 为 Number,则
- 如果 x 为 NaN ,则返回 false。
- 如果 y 为 NaN ,则返回 false。
- 如果 x 与 y 的 Number 值相同,则返回 true。
- 如果 x 为 + 0 且 y 为 −****0 , 返回 true。
- 如果 x 为 − 0 且 y 为 +0 ,则返回 true。****
- 返回 false。
如果 Type(x ) 为 String,则如果 x 和 y 是完全相同的字符序列(长度相同),则返回 true 和相应位置的相同字符)。否则,返回 false。
如果 Type(x ) 为布尔值,则如果 x 和 y 均为 true 或均为 false ,则返回 true 。否则,返回 false。
如果 x 和 y 引用同一对象,则返回 true 。 否则,返回 false。
如果 x 为 null 且 y 未定义 ,则返回 true。
如果 x 未定义 且 y 为 null ,则返回 true。
如果 Type(x ) 为 Number,Type(y ) 为 String,
则返回 比较结果 x == ToNumber(y)。
如果 Type(x ) 为 String 且 Type(y ) 为 Number,
则返回 比较结果 ToNumber(x ) == y。
如果 Type(x ) 为 Boolean,则返回比较结果 ToNumber(x ) == y。
如果 Type(x ) 为 String 或 Number,并且 Type(y ) 为 Object,
返回比较结果 x == ToPrimitive(y)。
如果 Type(x ) 是 Object 且 Type(y ) 是 String 或 Number,
返回比较结果 ToPrimitive(x ) == y。
返回 false。
看完这段官方文档,掘友们头都大了...
让我帮大家总结一下:
简单地说就是将左右两边都转换成数字比较,并且转换完毕以后,只要有一个为NaN就是false
举个例子:
js
console.log(false == []);//true
左边false转为数字是0,右边[ ]先调用valueOf,转不了,再调用toString变成空字符串,再转为Number为0,于是乎返回true。
掘友们看到这里,会感觉好像运算符都差不多,都是按照基本相同的规则进行运算的。没错!就是将操作数进行转换然后再操作。如果有不清楚类型转换的掘友可以移步我的上一篇文章(纯干货!类型转换的前因后果)。
结尾
掘友们学习完本文,就可以出去跟别人说:运算符,我真的会了!(我们这里讲的运算符)。轻轻松松拿捏。