算术运算符
加(+) 减(-) 乘(*) 除(/) 取余(%) 乘方(**)
// 加法运算
let a = 1
let b = a + 2 // 此时b等于3
// 减、乘、除同理
重点说下取余运算
取余运算即是字面含义,取除运算的余数,有时也叫模运算
// 例如:5 除以 3 商为1 余数为2
let a = 5 % 3 // 此时a存储的就是5除以3的余数2
let b = 6 % 2 // 此时能整除,所以余数为0,则b的值为0
// 小模大的余数
// 例如:3 除以 5,因为被除数比除数小,所以此时商为0,余数为3
let c = 3 % 5 // 此时 c = 3
let d = 2 % 10 // d = 2
// 所以:小值对大值取余运算时,余数为小值
接着来看乘方运算,乘方运算就是计算某个数的n
次方的结果
// 例如:计算5的平方
let a = 5 ** 2 // 等同于 a = 5 * 5 ==> a = 25
let b = 4 ** 4 // b = 256
let c = 2 ** 3 // c = 8
赋值运算符
等于(=) 加等于(+=) 减等于(-=) 乘等于(*=) 除等于(/=) 取余等于(%=) 乘方等于(**=)
看起来虽然多,但是比较比较容易理解
通常看到等号,要先计算等号右边
// 等于 以下两种都是等于运算,简单来说 就是对变量赋值
let a = 1
let b = 1 + 3
// 后续的带了运算符的都是同一个原理
// 例如: +=
let a = 1
a += 1 // 此时a=2,因为a += 1等价于 a = a + 1
// 其他同理
比较特殊的两个赋值运算符自增1(++)、自减1(--)
let a = 1
a++ // 此时a = 2,因为a的自增1运算,可以理解为 a += 1,也就是 a = a + 1
// 同理
let b = 3
b-- // 此时b = 2,因为b的自减1运算,可以理解为 b -= 1,也就是 b = b - 1
所以自增和自减,是在自身原始值的基础上,进行增1或者减1计算,并且会改变自身的值,有赋值运算的效果
需要注意的是,自增和自减还有一些需要注意的地方,以自增为例
let a = 1
let b = a++ // 请注意,此时 b = 1
原因是自增和自减,有两种情况,一种为后置自增或后置自减,另外一种为前置自增和前置自减,写法就是符号写在后面和前面的区别:前置自增:++a
、后置自增:a++
,自减同理。
接下来我们来看下上述为何b=1,而不是2,原因是后置自增和后置自减参与其他运算时,是先将原始值完整参与其他运算后,才进行自增;而前置自增和前置自减,是先将原始值自增或自减后,才参与其他运算。有一个先后顺序的问题。
let a = 1
let b = a++ // 此时 b = 1,a = 2
是因为这里有一个自增运算,同时还有一个赋值的等于运算,而a的自增是后置的,所以此处程序先将a的原始值1参与其他运算(此处是赋值运算)后才会自增,所以b接收到的是原始值1,而后,a自增为2。所以结果为:b=1 a=2
,自增运算同理。
let a = 1
let b = ++a // a = 2 b = 2
根据上述原理,此时a的前置自增,会先进行自增,后参与赋值运算,所以a=2 b=2
赋值运算符是非常简单的运算符,唯一需要关注的是自增和自减的情况。
比较运算符
大于(>)、小于(<)、相等(==)、不相等(!=)、全等(===)、不全等(!==)、大于等于(>=)、小于等于(<=)
比较运算符的结算结果,永远都是一个布尔值,条件成立为true
,不成立为false
let a = 2 > 1 // a = true
let b = -5 > 1 // b = false
需要注意的是相等和全等的区别(不相等和不全等同理)
相等判断运算时,如果两个运算数类型不相同时,会先转换为同一个类型,再进行比较,如果相等则结果为true
,反之false
,而不全等运算时,如果两个运算数类型不相同,则立刻返回false
,不进行任何类型转换,如果类型相同,则正常比较,根据结果返回值。
let a = 1 == "1" // 请注意,第一个运算数是数字1,第二个则是字符串1
// 此时 a = true,由于此时是相等比较,所以会将字符串1转换为数字后进行比较。
let b = 1 === "1" // b = false
// 此时,由于两个数类型不同,所以全等运算时,直接返回false
// 不相等和不全等同理
字符串再比较大小时,是按位比较各自的编码。"3">"20"
得到true
对象在做相等判断时,比较的是内存地址。
关于不同类型的值进行比较运算时,类型的转换规则参考下表:
值 | 字符串操作环境 | 数字运算环境 | 逻辑运算环境 | 对象操作环境 |
---|---|---|---|---|
undefined | “undefined” | NaN | false | Error |
null | “null” | 0 | false | Error |
非空字符串 | 不转换 | 字符串对应的数字值 | True | |
空字符串 | 不转换 | 0 | false | String |
0 | “0” | 不转换 | false | Number |
NaN | “NaN” | 不转换 | false | Number |
Infinity | “Infinity” | 不转换 | true | Number |
Number.POSITIVE_INFINITY | “Infinity” | 不转换 | true | Number |
Number.NEGATIVE_INFINITY | “-Infinity” | 不转换 | true | Number |
Number.MAX_VALUE | “1.7976931348623157e+308” | 不转换 | true | Number |
Number.MIN_VALUE | “5e-324” | 不转换 | true | Number |
其他所有数字 | “数字的字符串值” | 不转换 | true | Number |
true | “true” | 1 | 不转换 | Boolean |
false | “false” | 0 | 不转换 | Boolean |
对象 | toString() | value()或toString()或NaN | true | 不转换 |
Symbol | toString() | Error | true | Symbol |
BigInt | toString() | 不转换 | 除0n都是true | BigInt |
逻辑运算符
与(&&)、或(||)、非(!)
与运算和或运算可以理解为一个管道
与是和的意思,true
能通过,false
不通过
或就是或者, false
通过,true
不通过
非也叫取反。
逻辑运算符在运算时,会在计算时,临时将运算数转换为布尔值。
let a = 1
let b = 2
let c = a && b // 此时 c = 2
与运算时,a被转为布尔值true
,根据与运算符的特性,true
通过了,所以取到右边的值。c就等于右边的值2
let a = 0
let b = 2
let c = a && b // c = 0
此时a转为布尔值false
,false
不能通过&&
,所以停下来了,就取到了a的值,所以c等于0
或运算跟与运算则行为相反
关于各种值转为布尔值的情况,记住以下几个值即可:
JS中所有的值只有如下6个值可以转为false
,除了这6个值,其他的都是转为true
- 数字:
NaN
- 空指针:
null
- 未定义:
undefined
- 数字:
0
- 布尔值:
false
- 空字符串:
“”
非运算是将运算符之后的值临时转为布尔值后,取其相反值
let a = 1
let b = !a // b = false
a是数字1,转为布尔值为true
,所以相反值为false
,则b = false
let a = 0
let b = !a // b = true
let a = ""
let b = !a // b = true
let a = "JavaScript真是太简单了"
let b = !a // b = false