Javascript(ECMAScript) 自 ES6 之后在每年的 6月
都会进行一次版本更新,每每都会新增一些实验性的语法、运算符等,迄今为止已经增加了不少新成员,本文就介绍一些开发中能简化代码提升开发效率的运算符,走你~~
++(自增运算)
自增运算符,a++
效果等同 a = a + 1
在使用 ++、-- 运算符时,要非常注意前置和后置的使用对返回值的影响,有些时候这将带来难以发现的麻烦。
// 后置
var a = 1
a++ // => 1
console.log(a) // => 2
// 前置
var a = 1
++a // => 2
console.log(a) // => 2
--(自减运算)
自减运算符,a--
效果等同 a = a - 1
// 后置
var a = 2
a-- // => 2
console.log(a) // => 1
// 前置
var a = 2
--a // => 1
console.log(a) // => 1
** (幂运算)
求幂运算符(**)返回将第一个操作数加到第二个操作数的幂的结果。它等效于 Math.pow()
,不同之处在于它也接受 BigInts 作为操作数。
2 ** 3 // 8
3 ** 2 // 9
3 ** 2.5 // 15.588457268119896
10 ** -1 // 0.1
NaN ** 2 // NaN
void
void 运算符
对给定的表达式进行求值,然后返回 undefined
。
在使用立即执行的函数表达式时,可以利用 void
运算符让 JavaScript
引擎把一个 function
关键字识别成函数表达式而不是函数声明(语句)。
void function iife() { alert('iife') }();
当用户点击一个以 javascript: 开头的URI 时,它会执行URI中的代码,然后用返回的值替换页面内容,除非返回的值是undefined。void运算符可用于返回undefined。例如:
<a href="javascript:void(0);">
这个链接点击之后不会做任何事情,如果去掉 void(),
点击之后整个页面会被替换成一个字符 0。
a>
<p> chrome中即使<a href="javascript:0;">也没变化,firefox中会变成一个字符串0 p>
<a href="javascript:void(document.body.style.backgroundColor='green');">
点击这个链接会让页面背景变成绿色。
a>
注意,虽然这么做是可行的,但利用 javascript: 伪协议来执行 JavaScript 代码是不推荐的,推荐的做法是为链接元素绑定事件。
箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 void 运算符,来确保返回 undefined(如下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。
button.onclick = () => void doSomething();
在下面两行代码中,由于第一行代码没有使用小括号运算符,则 void
运算符优先执行,返回值 undefined
再与 1
执行减法运算,所以返回值为 NaN
。在第二行代码中由于使用小括号运算符明确 void
的操作数,减法运算符先被执行,然后执行 void
运算,最后返回值是 undefined
。
console.log(void 2 - 1); //返回NaN
console.log(void (2 - 1)); //返回undefined
+(一元加运算符)
一元加运算符,可将操作数转换为 Number
类型,效果等价于 Number()
方法,日常开发中可以替代 Number()
方法使用,简化代码。
var a = '222'
var b = 'abc'
console.log(+a) // => 222
console.log(+b) // => NaN
console.log(Number(a)) // => 222
console.log(Number(b)) // => NaN
-(一元减运算符)
一元减运算符:
var a = 3
console.log(-a) // => -3
var b = false
console.log(-b) // => -0
-0 === +0,
!(逻辑非)
逻辑非运算符,将操作数转化为布尔值后进行取反操作,与 Boolean()
效果相同。
!true // false
!false // true
!'' // true
!'Cat' // false
可以使用两个 !
运算符来强制将任何值转换为相应的布尔值。转换基于值的 真
或 假
。
n1 = !!true // true
n2 = !!{} // true
n3 = !!(new Boolean(false)) // false
n4 = !!false // false
n5 = !!"" // false
n6 = !!Boolean(false) // false
~( 位非)
按位非运算符,反转操作数的位。
const a = 5; // 00000000000000000000000000000101
const b = -3; // 11111111111111111111111111111101
~a // 11111111111111111111111111111010
console.log(~a); // -6
~b // 00000000000000000000000000000010
console.log(~b); // 2
位非运算实际上就是对数字进行取负运算,再减 1。例如:
console.log(~12 == -12 - 1)); // true
实际开发中可应用的场景:
indexOf()
返回值 >= 0 或者是 -1,使用~
判断值为 -1 的场景。
var a = 'abcdefg'
if(!(~a.indexOf('ddd'))) {
// 替代 a.indexOf('ddd') === '-1' 的写法
}
可以使用两个 ~~
按位非来替代正数的 Math.floor( )
,替代负数的 Math.ceil( )
。
不过要注意,对正数数值来说 ~~
运算结果与 Math.floor( )
运算结果相同,而对于负数数值来说与 Math.ceil( )
的运算结果相同:
~~4.5 // 4
Math.floor(4.5) // 4
Math.ceil(4.5) // 5
~~-4.5 // -4
Math.floor(-4.5) // -5
Math.ceil(-4.5) // -4
逻辑位运算符与逻辑运算符的运算方式是相同的,但是针对的对象不同。逻辑位运算符针对的是二进制的整数值,而逻辑运算符针对的是非二进制的值。
& (位与)
“&” 运算符(位与)用于对两个二进制操作数逐位进行比较,并根据下表所示的换算表返回结果。
“&”运算符换算表:
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
在位运算中,数值 1 表示 true,0 表示 false,反之亦然。
12 和 5 进行位与运算,则返回值为 4。
console.log(12 & 5); // 4
// 对数字 a & 1可以判断奇偶数,负数也同样适用,num & 1
console.log(11 & 1) // 1
console.log(12 & 1) // 0
下图以算式的形式解析了 12 和 5 进行位与运算的过程。通过位与运算,只有第 3 位的值为全为 true,故返回 true,其他位均返回 false。
|(位或)
“|”运算符(位或)用于对两个二进制操作数逐位进行比较,并根据如表格所示的换算表返回结果。
“|”运算符换算表:
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
12 和 5 进行位或运算,则返回值为 13。
console.log(12 | 5); // 13
// 对一个数字| 0可以取整,负数也同样适用,num | 0
1.3 | 0 // 1
-1.9 | 0 // -1
下图以算式的形式解析了 12 和 5 进行位或运算的过程。通过位或运算,除第 2 位的值为 false 外,其他位均返回 true。
在这里插入图片描述
^(位异或)
“^”运算符(位异或)用于对两个二进制操作数逐位进行比较,并根据如表格所示的换算表返回结果。
“^”运算符换算表:
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
12 和 5 进行位异或运算,则返回值为 9。
console.log(12 ^ 5); //返回值9
下图以算式的形式解析了 12 和 5 进行位异或运算的过程。通过位异或运算,第 1、4 位的值为 true,而第 2、3 位的值为 false。
,(逗号运算符)
逗号运算符是二元运算符,它能够先执行运算符左侧的操作数,然后再执行右侧的操作数,最后返回右侧操作数的值。
逗号运算符可以实现连续运算,如多个变量连续赋值。
var a = 1, b = 2, c = 3, d = 4;
等价于:
var a = 1;
var b = 2;
var c = 3;
var d = 4;
与条件运算符、逻辑运算符根据条件来决定是否执行所有或特定操作数不同的是,逗号运算符会执行所有的操作数,但并非返回所有操作数的结果,它只返回最后一个操作数的值。
在下面代码中,变量 a
的值是逗号运算之后,通过第二个操作数 c=2
的执行结果赋值得到的。第一个操作数的执行结果没有返回,但是这个表达式被执行了。
a = (b = 1, c = 2); //连续执行和赋值
console.log(a); //返回2
console.log(b); //返回1
console.log(c); //返回2
提示
逗号运算符可以作为仅需执行表达式的工具,这些表达式不需要返回值,但必须要运算。在特定环境中,可以在一个表达式中包含多个子表达式,通过逗号运算符让它们全部执行,而不用返回结果。
for
循环结构的小括号内包含 3
个表达式,第一个表达式为初始化值,第二个表达式为检测条件,第三个表达式为递增表达式。使用逗号运算符可以在 3
个表达式中添加多个额外的计算任务,但要确保第二个表达式的最后一个子表达式返回一个可控布尔值,否则会导致死循环。
for(var a = 1, b = 10, c = 100; ++c, a < b; a++, c--){
console.log(a * c);
}
逗号运算符的优先级是最低的。在下面代码中,赋值运算符优先于逗号运算符,也就是说数值 1
被赋值给变量 b
之后,继续赋值给变量 a
,最后才执行逗号运算符。
a = b = 1,c = 2; //连续执行和赋值
console.log(a); //返回1
console.log(b); //返回1
console.log(c); //返回2
?:(条件运算符)
三元条件运算符,val
(判断值)为真,取前者(问号后),为假取后者(冒号后)。
const val = 1
val ? 'val为真' : 'val为假' // => 'val为真'
??(空值合并运算符)
如果 ??
前面是 null
或 undefined
,取后面的默认值
null ?? 3 //3
undefined ?? 3 //3
7 ?? 3 //7
&&(逻辑与)
取假运算,从左往右执行,遇到假值就返回该假值,停止执行后续,否则就返回遇到的最后一个真值。
var [a, b, c] = [1, false, 0]
console.log(a && c) // => 0
||(逻辑或)
取真运算,从左往右执行,遇到真值就返回该真值,停止执行后续,否则就返回遇到的最后一个假值。
var [a, b, c] = [1, false, 0]
console.log(b || c || a) // => 1
...(扩展运算符)
可以在函数调用/数组构造时, 将 数组表达式
或者 字符串
在语法层面展开;还可以在构造字面量对象时, 将对象表达式按 key-value
的方式展开,在实际开发中非常常见。
字面量一般指 [1, 2, 3] 或者 {name: “mdn”} 这种简洁的构造方式
// 展开数组
const numbers = [1, 2, 3];
console.log([...numbers]) // => [1, 2, 3]
// 展开字符串
const strings = '1234567';
console.log([...strings]) // => [1, 2, 3, 4, 5, 6, 7]
// 展开对象
const person= { name: 'Ryan', gender: '男' }
console.log({...person}) // => { name: 'Ryan', gender: '男' }
// 函数调用中使用
const numbers = [1, 2, 3];
function sum(x, y, z) {
return x + y + z;
}
console.log(sum(...numbers)) // => 6
// 解构时使用
const person = { name: 'Alex', gender: '男', age: 18 }
const { age, ...rest } = person
console.log(age, {...rest}) // => 18,{ name: 'Alex', gender: '男' }
当数组的值或者对象的键值都为基本类型时,
[...],{...}
运算符可以实现对象或数组的深拷贝,反之只能实现浅拷贝。
?.(可选链操作符)
在引用的属性为空 (null
或者 undefined
) 的情况下不会引起错误,该表达式短路返回值是 undefined
。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined
。
const person = {
name: 'Alex',
cat: {
name: 'tom'
}
};
const tomName= person.dog?.name;
console.log(tomName);
// 返回 undefined
console.log(person.someNonExistentMethod?.());
// 返回 undefined
可以完全取代开发中使用的 a && a.children && a.children.name
的场景。
参考链接:
持续更新中。。。觉得不错点个收藏吧 ☆~~~