当前位置: 首页 > news >正文

JS核心操作符:从基础到ES6+

ECMAScript操作符

  • 一、一元操作符
    • 1.递增、递减操作符(++/- -)
    • 2.一元加和减(+/-)
  • 二、位操作符
    • 1.按位非(~)
    • 2.按位与(&)
    • 3.按位或(|)
    • 4.按位异或(^)
    • 5. 左移 (<<)
    • 6. 有符号右移 (>>)
    • 7. 无符号右移 (>>>)
  • 三、布尔操作符
    • 1. 逻辑非 (!)
    • 2. 逻辑与 (&&)
    • 3. 逻辑或 (||)
  • 四、算术操作符
    • 1. 加法操作符 (+)
    • 2. 减法操作符 (-)
    • 3. 乘法操作符 ( * )
    • 4. 除法操作符 ( / )
    • 5. 取模操作符 ( % )
  • 五、关系操作符
    • 特殊关系操作符( in )
    • 特殊关系操作符( instanceof )
  • 六、相等操作符
    • 1. 等于和不等于(== / !=)
    • 2. 全等和不全等(=== / !==)
  • 七、其它操作符
    • 1. 条件操作符(三元表达式)
    • 2. 赋值操作符( = )
    • 3. 逗号操作符(,)
  • 八 、ES6+ 新增操作符
    • 1. 指数操作符 (**)
    • 2. 链判断运算符( ?. )
    • 3. 空值合并操作符 (??)
    • 4. 逻辑赋值操作符 (&&=, ||=, ??=)
    • 5. 扩展运算符 (...)
  • 最后

操作符包括数学操作符(加、减)、位操作符、关系操作符和相等操作符等。操作符也是独特的,因为可用于各种值,包括字符串、数值、布尔值、对象。在应用给对象时会调用 valueOf() 或 toString() 方法来取得可计算的值。

一、一元操作符

含义:只操作一个值的操作符,是ES中最简单的操作符。

1.递增、递减操作符(++/- -)

递增和递减操作符搬运自C语言,有两个版本:前缀版后缀版,它们的主要区别在于返回值时机变量值变化时机

前缀版++a,递减一样(先递增/减,再返回新值 )

	let a = 29;const result = ++a; // 先递增,再返回新值 console.log(result); // 30(返回递增后的值)console.log(a);     // 30(变量已递增)

操作顺序:先执行 a = a + 1,然后返回新值
返回值:递增后的新值(30)
变量最终值:30

后缀版a++,递减一样(先返回新值,再递增/减 )

	let a = 29;const result = a++; // 先返回当前值,再递增 console.log(result); // 29(返回递增前的值)console.log(a);     // 30(变量已递增)

操作顺序:先返回当前值(29),然后执行 a = a + 1
返回值:递增前的原始值(29)
变量最终值:30

场景题:连续运算

	let b = 10;const c = b-- + --b; // 分解:// 1. b-- 返回10(当前值),b变为9// 2. --b 先减1(b变为8),返回8// 结果:c = 10 + 8 = 18
  • 对于字符串,如果是有效的数值形式,转化为数值再改变
  • 对于字符串,如果不是有效的数值,则将变量设置为NaN
  • 对于布尔值,false转换为0,true转换为1,再应用改变
  • 对于对象,则调用valueOf()取得可以操作的值

2.一元加和减(+/-)

一元加和减跟在高数中的用途一样
一元加放在变量前面对数值没有影响
一元减放在变量前面,主要用于把数值变为负值

// 数字类型保持不变console.log(+10);     // 10console.log(+3.14);   // 3.14// 字符串转换为数字console.log(+"5");    // 5 (数字)console.log(+"3.14"); // 3.14console.log(+"0xFF"); // 255 (十六进制转换)// 布尔值转换console.log(+true);   // 1console.log(+false);  // 0// 特殊值处理console.log(+null);   // 0console.log(+undefined); // NaNconsole.log(+"");     // 0 (空字符串) 

用途

// 字符串转数字
const num = +"42"; // 比parseInt()更快,但仅适用于纯数字字符串 
// 日期转时间戳
const timestamp = +new Date();  
  • 字符串:尝试解析为数字(失败则返回NaN)
  • 布尔值:true→1, false→0
  • null→0
  • undefined→NaN
  • 对象类型转换: 调用对象的valueOf()方法

二、位操作符

位操作符是 JavaScript 中直接操作数值的底层二进制位的操作符。这些操作符将操作数视为 32 位整数(0 和 1 的序列),执行位级操作后返回标准的 JavaScript 数值。

1.按位非(~)

它的作用但是返回数值的唯一补数。

let num1 = 25     //二进制 11001
let num2 = ~num1  //二进制 00110
console.log(num2) // -26

这里按位非作用得到了数值25,得到结果的结果是 -26。由此可以看出,按位非的最终效果是对数值取反并减1,就像下面的操作一样

let num1 = 25
let num2 = -num1 - 1
console.log(num2) // -26

尽管两者结果返回一样, 但是按位非操作的速度快得多,因为它是在数值的底层表示上完成的。

2.按位与(&)

将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的操作。

第一个数值的位第二个数值的位结果
111
100
010
000

规则: 两位都为 1 时结果才为 1

	5 & 31 // 分解:// 5 → 0101// 3 → 0011// & → 0001 → 1

应用场景: 检查奇偶性:num & 1 (1=奇数, 0=偶数)

3.按位或(|)

将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的操作。

第一个数值的位第二个数值的位结果
111
101
011
000

规则:任一位为 1 时结果为 1

	5 | 37// 分解:// 5 → 0101// 3 → 0011// | → 0111 → 7

应用场景:快速取整:3.14 | 0 → 3 (比Math.floor()更快)

4.按位异或(^)

同样有两个操作数,基于真值表中的规则,对每一位执行相应的操作。

第一个数值的位第二个数值的位结果
110
101
011
000

规则:两位不同时结果为 1

	5 ^ 36// 分解:// 5 → 0101// 3 → 0011// ^ → 0110 → 6

5. 左移 (<<)

规则:向左移动指定位数,右侧补 0

5 << 220// 分解:
// 5 → 0101
// << 2 → 010100 → 20

注意:左移会保留他所操作数值的符号,比如 -1左移五位,将得到 -64

6. 有符号右移 (>>)

规则:向右移动指定位数,左侧补符号位(保留正负号)

let oldValue = 64             //等于二进制 1000000
let newValue = oldValue >> 5  //等于二进制 0000010 ,即十进制2

7. 无符号右移 (>>>)

规则:向右移动,左侧补 0

对于正数来说,跟有符号右移效果相同。

let oldValue = 64             //等于二进制 1000000
let newValue = oldValue >> 5  //等于二进制 0000010 ,即十进制2

对于负数,无符号右移将负数的二进制表示为正数的二进制来表示,因为负数是其绝对值的二补数,所以右移之后结果变得非常大

let oldValue = -64            //等于二进制 11111111111111111111111111000000
let newValue = oldValue >> 5  //等于十进制 134217726  

三、布尔操作符

布尔操作符是 JavaScript 中用于逻辑判断和布尔值转换的核心操作符,主要包括逻辑非(!)、逻辑与(&&)和逻辑或(||)。这些操作符不仅用于布尔运算,还因其独特的短路特性在 JavaScript 编程中被广泛用于条件判断、默认值设置等场景。

1. 逻辑非 (!)

将操作数强制转换为布尔值后取反。

  • 如果操作数是对象,则返回 false
  • 如果操作数是空字符串,则返回 true
  • 如果操作数是非空字符串,则返回 false
  • 如果操作数是数值0,则返回 true
  • 如果操作数是数值非0数值(包括Infinity),则返回 false
  • 如果操作数是null,则返回 true
  • 如果操作数是NaN,则返回 true
  • 如果操作数是undefined,则返回 true
	console.log(!{});      // false console.log(!"");      // true console.log(!"hi");    // false console.log(!true);    // falseconsole.log(!false);   // trueconsole.log(!0);       // true  console.log(!1);       // false   console.log(!null);    // trueconsole.log(!undefined); // true

也可以同时用两个感叹号(!!),相当于调用转型函数Bollen()。无论操作数是什么类型,第一个感叹号总会返回布尔值。第二个感叹号对该布尔值取反,从而给出变量真正对应的布尔值。

	console.log(!!{});      // trueconsole.log(!!"");      // false console.log(!!"hi");    // trueconsole.log(!!true);    // trueconsole.log(!!false);   // falseconsole.log(!!0);       // falseconsole.log(!!1);       // trueconsole.log(!!null);    // falseconsole.log(!!undefined); // false

2. 逻辑与 (&&)

当且仅当所有操作数都为真时返回真

第一个操作数第二个操作数结果
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

逻辑与操作数可用于任何类型的操作数,不限于布尔值。如果有操作数不是布尔值,则逻辑与不一定会返回布尔值,而是遵循以下规则

  • 如果第一个操作数是对象,则返回第二个操作数
  • 如果第二个操作数是对象,则只有第一个操作数值为true才会返回该对象
  • 如果两个操作数都是对象,则返回第二个操作数
  • 如果有一个操作数是null,则返回null
  • 如果有一个操作数是NaN,则返回NaN
  • 如果有一个操作数是undefined,则返回undefined
	console.log(Object && 1);      // 1console.log(1 && Object);      // Object console.log(1 && null);    // null 

逻辑与操作符是一种短路操作符,如果第一个操作数决定了结果,那么永远不会对第二个操作室求值。
**如果第一个操作数是false,**那么无论第二个操作数是什么值,结果都不会等于true。

例子:

let result = bool && somethingError 

如果bool 值为 true,那么求值时会报错
如果bool 值为 false,那么逻辑与操作符不会对其求值,因此右边的操作数是没有意义的。

3. 逻辑或 (||)

当任一操作数为真时返回真

第一个操作数第二个操作数结果
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

逻辑或与逻辑或类似,如果有操作数不是布尔值,则逻辑与不一定会返回布尔值,而是遵循以下规则

  • 如果第一个操作数是对象,则返回第一个操作数
  • 如果第一个操作数求值为false,则返回第二个操作数
  • 如果两个操作数都是对象,则返回第一个操作数
  • 如果两个操作数是null,则返回null
  • 如果两个操作数是NaN,则返回NaN
  • 如果两个操作数是undefined,则返回undefined
   console.log(Object || 1);      // Object console.log(0 || Object);     // Object console.log(1 || null);       // 1 console.log(null || null);       // null 

逻辑或与逻辑与类似,只不过是第一个值为true ,就不会执行后续的值了。

四、算术操作符

包含标准四则运算操作符(+, -, *, /, %),其行为遵循数学规则但有特殊边界处理。

1. 加法操作符 (+)

加法操作符用于求两个数的和,比如 let result = 1 + 2

如果两个操作符都是数值,遵循以下规则

  • 如果有一任意操作符是NaN,则返回NaN
  • 如果是Infinity 加 Infinity ,则返回 Infinity
  • 如果是-Infinity 加 -Infinity ,则返回 -Infinity
  • 如果是 Infinity 加 -Infinity ,则返回 NaN
  • 如果是+0 加 +0 ,则返回 +0
  • 如果是-0 加 +0 ,则返回 +0
  • 如果是-0 加 -0 ,则返回 -0

如果有一个操作符是字符串,遵循一下规则

  • 如果是两个字符串,则将第二个字符串拼接到第一个字符串后面
  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接。
  • 如果有任一操作数是对象、数值或布尔值,则调用它们的 toString() 方法获取字符串
  • 对于undefined 和 null,则调用String() 函数,分别获取"undefined" 和 “null”
	5 + '5'  // '55'5 + {}  // '5[object Object]'5 + null  // 5 (null → 0)'5' + null  // '5null' (null → 'null')5 + undefined  // NaN (undefined → NaN)

2. 减法操作符 (-)

与加法操作符一样,减法操作符也有一组规则用于处理ES中不同类型的转换

  • 如果两个操作符都是数值,则执行数学减法运算并返回结果
  • 如果有一任意操作符是NaN,则返回NaN
  • 如果是Infinity 减 Infinity ,则返回 NaN
  • 如果是-Infinity 减 -Infinity ,则返回 NaN
  • 如果是 Infinity 减 -Infinity ,则返回 Infinity
  • 如果是 -Infinity 减 Infinity ,则返回 -Infinity
  • 如果是+0 减 +0 ,则返回 +0
  • 如果是+0 减 -0 ,则返回 -0
  • 如果是-0 减 -0 ,则返回 +0
  • 如果任一操作数是字符串、布尔值、null、undefined,则先在后台使用number()将其转化为数值,再根据前面的规则执行数学运算。如果转换结果是NaN,则减法运算结果是NaN。
  • 如果有任一操作符是对象,则调用 valueOf() 取得表示它的值。如果该值是NaN,则减法计算结果是NaN。如果对象没有valueOf() 方法,则调用其 toString()方法,然后再将其得到的字符串转换为数值。
	5 - 3      // 2'5' - 3    // 2 ( '5' 转为 5 )5 - '3'    // 2 ( '3' 转为 3 )'a' - 3    // NaN (无法转换为数字)NaN - 1    // NaN5 - null   // 5 null被转换为0

3. 乘法操作符 ( * )

乘法操作符由一个星号( * )表示,可以用于两个数值的乘积

乘法操作符 遵循以下规则

  • 如果两个操作符都是数值,则执行数学乘法运算并返回结果
  • 如果有一任意操作符是NaN,则返回NaN
  • 如果是Infinity 乘 0 ,则返回 NaN
  • 如果是Infinity 乘 非0的有限值 ,则根据第二个操作数的符号返回 Infinity 和 -Infinity
  • 如果是Infinity 乘 Infinity,则返回 Infinity
  • 如果有不是数值的操作数,则先在后台用number()将其转换为数值,然后再执行上面的规则
	2 * 3          // 6'2' * '3'      // 6 (字符串转为数字)Infinity * 0   // NaN

4. 除法操作符 ( / )

除法操作符由一个斜杠( / )表示,可以用于计算第一个操作数除以第二个操作数的商

除法操作符 遵循以下规则

  • 如果两个操作符都是数值,则执行数学除法运算并返回结果
  • 如果有一任意操作符是NaN,则返回NaN
  • 如果是Infinity 除 Infinity ,则返回 NaN
  • 如果是0 除 0,则返回 NaN
  • 如果是非0的有限值 除 0 ,则根据第一个操作数的符号返回 Infinity 和 -Infinity
  • 如果是Infinity 除 任何数值,则根据第二个操作数的符号返回 Infinity 和 -Infinity
  • 如果有不是数值的操作数,则先在后台用number()将其转换为数值,然后再执行上面的规则
	 6 / 3        // 2 '222' / 0    // Infinity0 / 0        // NaNtrue / 0.5   //2

5. 取模操作符 ( % )

取模(余数)操作符由一个百分比符号( % )表示,返回除法的余数

取模操作符 遵循以下规则

  • 如果操作数是数值,则执行常规除法运算,返回余数
  • 如果被除数是无限值,除数是有限值,则返回NaN
  • 如果被除数是有限值,除数是0,则返回NaN
  • 如果是Infinity 除 Infinity ,则返回 NaN
  • 如果被除数是有限值,除数是无限值,则返回被除数
  • 如果被除数是0,除数不是0,则返回0
  • 如果有不是数值的操作数,则先在后台用number()将其转换为数值,然后再执行上面的规则
	 5 % 2  // 1-5 % 2  // -15.5 % 2  // 1.510 % 0  // NaN11 % Infinity  // 11

五、关系操作符

关系操作符执行比较两个值的操作,包括小于( < )、大于( > )、小于等于( <= )、大于等于( >= ),它们返回布尔值(true或false)表示比较结果。

  • 如果操作数都是数值,则执行数值比较
  • 如果操作数都是字符串,则逐个比较字符串中对应字符的编码
  • 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较
  • 如果有任一操作数是对象,则调用valueOf()方法,取得结果后再根据前面的规则比较,如果没有valueOf(),则调用toString()方法。
  • 如果任一操作数是布尔值,则将其转换为数值再执行比较
console.log('23' < '3');   // true '2'的编码是50,'3'的编码是51
console.log('10' > 5);    // true (10 > 5) 字符串转为数字  
console.log('a' > 5);     // false 'a'会转换为NaN
// 布尔值参与比较(true→1, false→0)
console.log(true > false);   // true (1 > 0)
console.log(false < 1);      // true (0 < 1) 
// null 和 undefined 特殊处理
console.log(null < 0);      // false (null→0, 0<0? false)
console.log(null <= 0);     // true (null→0, 0<=0? true)
console.log(undefined > 0); // false (undefined→NaN)console.log({} > 0); // false ({}→'[object Object]')

特殊关系操作符( in )

检查属性是否存在于对象或其原型链中

	const car = { make: 'Toyota', year: 2020 };// 对象属性检查console.log('make' in car);     // trueconsole.log('model' in car);    // false// 数组索引检查const colors = ['red', 'green', 'blue'];console.log(0 in colors);       // true (索引0存在)console.log(3 in colors);       // false (索引3不存在)console.log('length' in colors);// true (继承属性)// 原型链属性console.log('toString' in car); // true (来自Object.prototype)

特殊关系操作符( instanceof )

检查对象是否是特定构造函数的实例

	// 基础类型console.log('hello' instanceof String);   // false (原始类型)console.log(new String('hello') instanceof String); // true// 内置对象const arr = [1, 2, 3];console.log(arr instanceof Array);      // trueconsole.log(arr instanceof Object);     // true (所有对象都是Object的实例)// 自定义类class Vehicle {}class Car extends Vehicle {}const myCar = new Car();console.log(myCar instanceof Car);      // trueconsole.log(myCar instanceof Vehicle);  // trueconsole.log(myCar instanceof Object);   // true// 边界情况console.log(null instanceof Object);    // falseconsole.log(undefined instanceof Object); // false

六、相等操作符

判断两个变量是否相等

1. 等于和不等于(== / !=)

等于用两个等于号表示( == ),如果相同则返回true。不等于用( != )表示,如果不相等则返回true。这两个操作符都会先进行强制转换在确定操作数是否相等。
规则

  • 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false转换为0,true转换为1
  • 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等
  • 如果一个操作数是对象,另一个不是,则调用对象的valueOf()方法取得其原始值,再根据前面的规则进行比较
  • null与undefined相等
  • null与undefined不能转换为其他类型的值进行比较
  • 如果有任一操作数是NaN,则相等返回false,不相等返回true,NaN不等于NaN</.font>
  • 如果两个操作数都是对象,则比较他们是不是同一个对象。如果两个操作数都指向同一个对象,则返回true,否则不相等
console.log(5 == '5');    // true (5 == 5)
console.log('' == 0);     // true (0 == 0) 
console.log(true == 1);   // true (1 == 1)
console.log(false == 0);  // true (0 == 0) 
console.log(null == undefined);  // true   const obj = { toString: () => '5' };
console.log(obj == 5);    // true ('5' == 5 → 5 == 5) console.log([] == 0);     // true ([]→''→0)
console.log([] == '');    // true
console.log([] == []);    // false (不同引用)
console.log(NaN == NaN);    // false 

放一张比较图
在这里插入图片描述

2. 全等和不全等(=== / !==)

全等和不全等操作符与上面类似,只不过它们在比较时不会转换操作数

console.log(5 === '5');     // false
console.log(true === 1);    // false 
console.log(5 === 5);       // true
console.log(null === undefined);   // false 
注意:由于相等和不相等操作符存在类型转换问题,因此推荐使用全等和不全等操作符。这样有助于在代码中保持数据的完整性。

七、其它操作符

1. 条件操作符(三元表达式)

语法:variable = 条件 ? 表达式1 : 表达式2
上面代码执行了条件赋值操作,根据条件的值决定将哪个值赋值给变量 variable。如果条件值为true,则赋值表达式1。如果为false则赋值表达式2

// 基本用法
const age = 20;
const status = age >= 18 ? '成年人' : '未成年人';
console.log(status); // "成年人"// 嵌套条件
const score = 85;
const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D';
console.log(grade); // "B"// 函数返回值
function getFee(isMember) {return isMember ? '$2.00' : '$10.00';
}
console.log(getFee(true));  // "$2.00"
console.log(getFee(false)); // "$10.00"

2. 赋值操作符( = )

简单赋值用等于号( = ),表示将右边的值赋值给左边的变量

let x = 10; // 基本赋值
const y = x; // 值拷贝// 链式赋值(从右向左)
let a, b, c;
a = b = c = 5;  
console.log(a, b, c); // 5, 5, 5 
// 解构赋值
const [x, y] = [1, 2]; 
const { name, age } = user;

3. 逗号操作符(,)

逗号操作符可以用来在一条语句中执行多个操作 let num1 = 1,num2 = 2,num3 = 3
基本用法

let a = (1, 2, 3); // a = 3 a将被赋值表达式中最后一项

for循环中使用

for (let i = 0, j = 10; i < j; i++, j--) {console.log(i, j);
}
// 输出:0 10, 1 9, ..., 4 6

箭头函数返回值

	const getData = () => (fetchData(), processResult());// 等价于:const getData = () => {fetchData();return processResult();};

八 、ES6+ 新增操作符

1. 指数操作符 (**)

	Math.pow(3,2) === 3**2    //9

指数赋值操作符 **= 进行执行指数运算和结果的赋值操作

	let num = 2num **= 3 // 等同于 num = num ** 3console.log(num) // 8let b = 4 b **= 3  // 等同于 b = b * b * b;  64

2. 链判断运算符( ?. )

如果读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在。比如,读取message.body.user.firstName这个属性,安全的写法是写成下面这样。

	// 错误的写法const  firstName = message.body.user.firstName || 'default';// 正确的写法const firstName = (message  && message.body  && message.body.user  && message.body.user.firstName) || 'default';

上面例子中,firstName属性在对象的第四层,所以需要判断四次,每一层是否有值。

三元运算符?:也常用于判断对象是否存在。
这样的层层判断非常麻烦,因此 ES2020 引入了“链判断运算符”(optional chaining operator)?.,简化上面的写法。

	const firstName = message?.body?.user?.firstName || 'default';

上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为null或undefined。如果是的,就不再往下运算,而是返回undefined。

	a?.b   // 等同于 a == null ? undefined : a.ba?.b() // 等同于 a == null ? undefined : a.b()

规则:

  • 本质上,?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行,直接返回undefined
  • 如果属性链有圆括号,链判断运算符对圆括号外部没有影响,只对圆括号内部有影响。
	(a?.b).c // 等价于 (a == null ? undefined : a.b).c
  • 右侧不得为十进制数值、
  • 不能用于赋值
  • 不能用于未声明的变量、构造函数、模板字符串等

3. 空值合并操作符 (??)

只有运算符左侧的值为nullundefined时,才会返回右侧的值。

	console.log(null ?? "default"); // "default"console.log(undefined ?? "default"); // "default"console.log(0 ?? 100); // 0console.log("" ?? "default"); // ""console.log(false ?? true); // false

这个运算符的一个目的,就是跟链判断运算符?.配合使用,为nullundefined的值设置默认值。

const value = obj.key?.value ?? 404;

上面代码中,如果obj.key是null或undefined,或者 obj.key.value 是null或undefined,就会返回默认值404。也就是说,这一行代码包括了两级属性的判断。

这个运算符很适合判断函数参数是否赋值。

	function Component(props) {const enable = props.enabled ?? true;// …}//等同于这种写法function Component(props) {const { enabled: enable = true} = props;// …}

注意:??本质上是逻辑运算,它与其他两个逻辑运算符&&||有一个优先级问题,它们之间的优先级到底孰高孰低。优先级的不同,往往会导致逻辑运算的结果不同。
现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错

	// 错误写法:语法错误a ?? b || c; // 正确写法:使用括号(a ?? b) || c;a ?? (b || c);

应用场景

	// 1. 配置默认值const PORT = process.env.PORT ?? 3000;// 2. 函数参数默认值function connect(options = {}) {const timeout = options.timeout ?? 5000;const retries = options.retries ?? 3;}// 3. 结合解构使用const { width = 100, height = null } = element.getDimensions();const actualHeight = height ?? 200;

4. 逻辑赋值操作符 (&&=, ||=, ??=)

ES2021 引入,简化条件赋值操作
这三个运算符 ||=、&&=、??= 相当于先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算。

	// 逻辑或赋值 (||=)let x = 0;x ||= 10; // 等价于 x = x || 10console.log(x); // 10// 逻辑与赋值 (&&=)let y = 5;y &&= 10; // 等价于 y = y && 10console.log(y); // 10// 空值合并赋值 (??=)let z = null;z ??= 15; // 等价于 z = z ?? 15console.log(z); // 15
	// 旧方式if (!obj.prop) {obj.prop = defaultValue;}// 新方式obj.prop ||= defaultValue;// 旧方式user.id = user.id || 1;// 新方式user.id ||= 1;

5. 扩展运算符 (…)

ES2015 (ES6) 引入,功能强大且应用广泛

	// 1. 数组复制 (浅拷贝)const original = [1, 2, { a: 3 }];const copy = [...original]; copy[2].a = 4; // 影响原数组中的对象// 2. 数组合并const arr1 = [1, 2];const arr2 = [3, 4];const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]// 3. 数组去重const duplicates = [1, 2, 2, 3, 4, 4];const unique = [...new Set(duplicates)]; // [1, 2, 3, 4]// 4. 字符串转数组const str = "hello";const chars = [...str]; // ['h','e','l','l','o']  

对象展开 (ES2018)

    // 对象复制 (浅拷贝)const obj = { a: 1, b: { c: 2 } };const clone = { ...obj };// 对象合并const defaults = { theme: "light", fontSize: 16 };const userSettings = { fontSize: 18, darkMode: true };const settings = { ...defaults, ...userSettings };// { theme: "light", fontSize: 18, darkMode: true }

其他的扩展运算符用法可以看这里数组一些常用的方法

最后

end ,参考【JS高级程序第四版】,阮一峰ES6入门 运算符的扩展

http://www.lryc.cn/news/574670.html

相关文章:

  • (ICML-2023)BLIP-2:使用冻结图像编码器与大型语言模型的语言-图像预训练引导方法
  • SQL Server 查询数据库及数据文件大小
  • 使用 spark-submit 运行依赖第三方库的 Python 文件
  • RGB相机 vs 灰度相机
  • Apache Flink Kafka 写连接器源码深度剖析
  • java-SpringBoot框架开发计算器网页端编程练习项目【web版】
  • Drag-and-Drop LLMs: Zero-Shot Prompt-to-Weights
  • DataSophon 1.2.1集成Flink 1.20并增加JMX 监控
  • pyqt setContentsMargins
  • 网络安全攻防:2025年新型钓鱼攻击防御指南
  • 零基础搭建Spring AI本地开发环境指南
  • LT8311EX一款适用于笔记本电脑,扩展坞的usb2.0高速运转芯片,成对使用,延伸长度达120米
  • 202564读书笔记|《土耳其:换个地方躺平(轻游记)》——旅行的时候,绮丽多姿的真实世界向我打开
  • Python核心库Pandas详解:数据处理与分析利器
  • 【Java开发日记】我们详细地讲解一下 Java 异常及要如何处理
  • Springboot项目中使用手机号短信验证码注册登录实现
  • Vue项目使用defer优化页面白屏,性能优化提升,秒加载!!!
  • 【服务器】教程 — Linux上如何挂载服务器NAS
  • 帮助装修公司拓展客户资源的微信装修小程序怎么做?
  • STM32 环境监测与控制系统的设计与实现
  • Vue3+el-table-v2虚拟表格大数据量多选功能详细教程
  • STM32[笔记]--4.嵌入式硬件基础
  • 攻防世界-MISC-MeowMeowMeow
  • Unity小工具:资源引用的检索和替换
  • 深入研究:小红书笔记详情API接口详解
  • Linux环境下MariaDB如何实现负载均衡
  • 一文了解AI Agent的幕后基础设施
  • 记一次 Kafka 磁盘被写满的排查经历
  • 采用ArcGIS10.8.2 进行插值图绘制
  • macOS - 快速上手使用 YOLO