ECMA-262描述了一组用于操作数值的操作符,包括算术操作符、位操作符、关系操作符、相等操作符。适用于很多值,包括数值、布尔、字符串、Undefined、Null、Symbol和对象。
一、一元操作符
所谓一元操作符就是只能操作一个数值。
1、递增 / 递减操作符
1.1、前置累加 / 前置累减
特点:先操作,再赋值。比如
let num1 = 4, num2 = 4
console.log(--num1) // 3
console.log(++num2) // 5
1.2、后置累加 / 后置累减
特点:先赋值,再操作。比如
let num1 = 4, num2 = 4
console.log(num1--) // 4
console.log(num2++) // 4
console.log(num1) // 3
console.log(num2) // 5
2、一元加减操作符
let num1 = 4, num2 = 4
console.log(-num1) // -4
console.log(+num2) // 4
二、位操作符
位操作符是作用于最基本的层次上,即对数据所储存的二进制位进行操作。
1、按位非
按位非操作符是由一个波浪线(~)表示,返回操作数的反码,效果为操作数的负值(不一定是负数,只是相对于操作数的负值)减一。
// 非运算符-----操作数符号转换
const num = 555
console.log(~num) // -556
2、按位与
按位与操作符是由一个和号字符(&)表示,实质为将两个操作数底层表示的二进制一一对其,两者位数都为1时返回1,否则为0。比如
4 & 5 = 4
等同于(相同部分)0100 & (相同部分)0101 = (相同部分)0100(十进制为4)
// 与运算符-----判断奇偶性
const andArr = [1, 2, 3, 4, 5]
andArr.forEach(item => {
(item & 1 === 1) && console.log(`${item}是奇数`)
})
3、按位或
按位与操作符是由一个和号字符(|)表示,实质为将两个操作数底层表示的二进制一一对其,两者位数有一者为1时返回1,否则为0。比如
4 | 5 = 5
等同于(相同部分)0100 | (相同部分)0101 = (相同部分)0101(十进制为5)
// 或运算符-----将偶数变为奇数【用于补位场景】
const orrArr = [1, 2, 3, 4, 5]
const onchangeArr = orrArr.map(item => item | 1)
console.log(onchangeArr)
4、按位异或
按位与操作符是由一个和号字符(^)表示,实质为将两个操作数底层表示的二进制一一对其,两者位数不同时返回1,否则为0。比如
4 ^ 5 = 1
等同于(相同部分)0100 ^ (相同部分)0101 = (相同部分)0001(十进制为1)
利用异或 (a ^ b) ^ b === a
的特性,可以应用于一般简单的加密解密,比如
// 异或运算符-----简单加密
const clearTextArr = '绿谷出久'
const key = 313
const hander = (str, key) => {
const charCode = str.charCodeAt() ^ key
return String.fromCharCode(charCode)
}
const encryptionAndDecrypt = ([...data], key) => {
let result = ''
data.forEach(item => {
result = result.concat(hander(item, key))
})
return result
}
const ciphertext = encryptionAndDecrypt(clearTextArr, key)
console.log(ciphertext) // 翆贎僃佼
console.log(encryptionAndDecrypt(ciphertext, 313)) // 绿谷出久
5、左移
左移操作符是由两个小于号字符(<<)表示,实质为将操作数底层表示的二进制整体左移n位(自定义),右侧空白位补零。比如
4 << 2 = 16
等同于(多个0)0100 << 2 = (多个0)010000(十进制为16)
利用二进制进位的特性,一般亦可以应用于rgb转16进制(配合使用正则和toString方法)
// 左移运算符-----rgb转十六进制
const rgb = 'rgb(24, 255, 78)'
const onchangeRgb = data => {
let result = ''
const rgbNumArr = data.match(/\d+/g) // 提取数值部分
const illegalArr = rgbNumArr.filter(item => item > 255 || item < 0) // 收集非法数值
if (rgbNumArr.length !== 3 || illegalArr.length !== 0) {
console.log('输入色值非法')
return
}
result = (rgbNumArr[0] << 16 | rgbNumArr[1] << 8 | rgbNumArr[2]).toString(16) // 利用或运算符补位
result = result.padStart(6, '0') // 十六进制色值位数不够补0
return `#${result}`
}
console.log(onchangeRgb(rgb))
其外拓展:十六进制转rgb,使用正则和parseInt(str, 16)方法
// 十六进制转rgb
const colorCode = '#18ff4e'
const onchangeCollorCode = data => {
const result = data.match(/[a-fA-F\d]{2}/g).map(item => parseInt(item, 16)) // 剔除#符号并切分
if (result.length !== 3) {
console.log('输入色值非法')
return
}
return `rgb(${result[0]}, ${result[1]}, ${result[2]})`
}
console.log(onchangeCollorCode(colorCode))
6、有符号右移
按位与操作符是由两个大于号字符(>>)表示,实质为将两个操作数底层表示的二进制整体右移n位(除却第一位的符号位),左侧空白为补符号位数值。比如
4 >> 1 = 2
等同于(符号位0+多个0)0100 >> 1 = (符号位0+多个0)0010(十进制为2)
注意:当右移位数超出操作数的有效最长位,操作数为正数则为0,负数则为-1,比如
4 >> 3 = 0
等同于(符号位0+多个0)0100 >> 3 = (符号位0+多个0)0000(十进制为0)
-4 >> 3 = 0
等同于(符号位1+多个1)1100 >> 3 = (符号位1+多个1)1111(十进制为-1【减1再整体取反就为其值对应的负值(正数),比如-1的负值是正数1】)
。
7、无符号右移
按位与操作符是由三个大于号字符(>>>)表示,实质为将两个操作数底层表示的二进制整体右移n位(包括第一位的符号位),左侧空白为补零。比如
4 >>> 1 = 2
等同于(符号位0+多个0)0100 >> 1 = (符号位0+多个0)0010(十进制为2)
-4 >>> 1 = 2
等同于符号位1+27个1+1100 >> 1 = 符号位0+27个1+1110(十进制为 2147483646)
。
三、布尔操作符
1、逻辑非操作符(!)
返回值为布尔型,若操作数为布尔型,则返回其对立布尔值;若操作数不是布尔型,则先转化为布尔型,再返回其对立布尔值。
2、逻辑与操作符(&&)
返回值不一定为布尔值,遵循规则如下
当前者为true
(如果不是布尔值,则当其转化为布尔值后)时,则会返回(执行)后者语句;当前者为false
(如果不是布尔值,则当其转化为布尔值后)时,则只会返回(执行)前者语句。
11 && console.log(22) // 22
console.log(11) && console.log(22) // 11
3、逻辑与操作符(||)
返回值不一定为布尔值,遵循规则如下
当前者为true
(如果不是布尔值,则当其转化为布尔值后)时,则只会返回(执行)前者语句;当前者为false
(如果不是布尔值,则当其转化为布尔值后)时,则会返回(执行)后者语句。
11 || console.log(22) // 11
console.log(11) && console.log(22) // 11 22
四、乘性操作符
1、乘法操作符(*),主要特性为
当二者都是数值型,则按照正常乘法规则;
当存在一者为NaN时,则为NaN(注意:任何与NaN参与的操作,返回都是NaN);
当存在其他数据类型时,先通过Number方法(注意:Number的转化规则)转化为数值型,在进行计算。
2、除法操作符(/),主要特征为
当两者为数值,则按正常计算;
当除数为0,被除数不为0时,即0/3
,则为0;
当除数不为0,被除数为0,即3/0、-3/0
,则为Infinity、-Infinity
;
当两者都为0,即0/0
,则为NaN
;
当两者不为数值时,比如true/true // 1
,先通过Number方法(注意:Number的转化规则)转化为数值型,在进行计算。
3、求模操作符(%),主要特征为
当两者为整形数值,则按正常除法计算,得余数;
当两者存在小数时,即1%0.5
,则为0;
当前者为0,后不为0时,即0%3
,则为0;
当前者不为0,被后者为0,即3%0、-3%0
,则为NaN
;
当两者都为0,即0%0
,则为NaN
;
当两者不为数值时,比如true/true // 1
,先通过Number方法(注意:Number的转化规则)转化为数值型,在进行计算。
五、加性操作符
1、加法操作符(+),主要特征为
当两者都为数值,则按正常计算;
当两者存在NaN时,则为NaN(注意:任何与NaN参与的操作,返回都是NaN);
当两者都为-0
时,则为-0
(其余0都为+0【ps:’+'符号浏览器会省略】);
当两者都是true、false、null
时,则会先将两者转化为数值,再得加数;
当两者存在undefined
时,则为NaN
;
当两者存在字符串或则对象时,则返回结果类型为String
(如果另者操作数为数值,则会将它转化为字符串,从而拼接)。
2、减法操作符(-),主要特征为
当两者都为数值,则按正常计算;
当两者存在NaN时,则为NaN(注意:任何与NaN参与的操作,返回都是NaN);
当两者都为-0
和+0
时,则为-0
(其余0都为+0【ps:’+'符号浏览器会省略】);
当两者存在(都是)字符串、布尔、null、undefined时,先通过Number方法(注意:Number的转化规则)转化为数值型,在进行计算;
当两者存在(都是)对象,先通过valueOf方法,若没有此方法则通过toString方法,最后通过Number方法(注意:Number的转化规则)转化为数值型,在进行计算;
六、关系操作符
大于(>)、小于(<)、大于等于(>=)、小于等于(<=),主要特征为
当两者都为数值,则按正常计算,比较数值;
当两者存在NaN时,则为false;
当两者都为字符串,则比较字符编码值(比较开始字符编码值。若不同,得出结论;若相同,继续比较下一个字符,直到比较出不同或某个字符串全部遍历完成,得出结论);
当一者是字符串、布尔、null、undefined,另者是数值,则通过Number方法对字符串等进行转数值,再进行数值比较,得出结论。
当一者是对象,先通过valueOf方法,若没有此方法则通过toString方法,最后通过Number方法(注意:Number的转化规则)转化为数值型,在进行比较,得出结论;
七、相等操作符
1、相等操作符(==
)【存在隐式转化】
当两者为同类型时,不转化类型,直接比较值是否相同;
当两者类型不同时,先转化Number数据类型,再比较值;比如[] == true // false
解析流程:发现两者类型不同,则将[]转化为Number([])为0,将true转化为Number(true)为1;再进行比较得出结论。
特殊情况:null == undefined // true
2、全等操作符(===
),值和类型都要相等,比如null === undefined // false
八、条件运算符(condition ? expiry_1 : expiry_2)
const num = true ? 1 : 2
console.log(num) // 1