ES6 运算符

目录

1、指数运算符

2、可选链运算符

可选链不能用于赋值

可选链可访问数组

短路计算

括号的影响

3、空值合并运算符

基本用法

与 ?. 一起使用

短路

与 || 或 && 一起使用

4、逻辑赋值运算符

基本用法


1、指数运算符

ES6新增指数运算符:**

大多数运算符是左结合,指数运算度是又结合,多个指数运算符连用时是从左右边开始计算的。

// 指数运算符
console.log(2 ** 2); // 4
console.log(2 ** 3); // 8
// 从右边开始计算 相当于 2 ** (2 ** 3)
console.log(2 ** 2 ** 3); // 256
// 从左计算需要加括号
console.log((2 ** 2) ** 3); // 64

指数运算符和等号结合,形成一个新的赋值运算符( **= )。

let num = 2;
// 相当于 num = num * num; num = num ** 2;
num **= 2;
console.log(num); // 4

2、可选链运算符

写法:?.

开发过程中,想要读取一个对象中可能不存在的值,往往需要判断一下。没有可选链操作符之前是这样写。

let animal = {
  cat: {
    name: "Tom",
    sex: "男",
    age: 1,
  },
};
let dog = (animal && animal.dog && animal.dog.name) || "default";

上面代码,name属性在对象中的第三层,需要每一层判断一下属性是否存在。

使用可选链就会方便很多。如果左侧对象是null或者undefined时,表达式将会短路计算直接返回undefined。

let dog = animal.dog?.name || "default";

animal.dog?.name 相当于

(animal.dog === undefined || animal.dog === null) ? undefined : animal.dog.name;

调用函数也是一样的,如果函数不存在,自动返回undefined,而不是报错。

animal.eat(); // TypeError: animal.eat is not a function
animal.eat?.(); // undefined

 注意:如果存在一个属性名但不是函数,使用可选链依然会报错。

let animal = {
  cat: {
    name: "Tom",
    sex: "男",
    age: 1,
    eat: "干饭",
  },
};
animal.cat.eat?.(); // TypeError: animal.cat.eat is not a function

可选链不能用于赋值

let cat = {};
cat?.name = "Tom"; // SyntaxError: Invalid left-hand side in assignment

可选链可访问数组

let arr = ["Tom"];
let arrayItem = arr?.[0];
console.log(arrayItem); // Tom

短路计算

当在表达式中使用可选链时,如果左操作数是null或undefined时,表达式将不会被计算。

let cat = {
  name: "Tom",
  age: 1,
};
cat.sex?.[cat.age++];
console.log(cat.age); // 1

括号的影响

对括号外部没影响,只对括号内部有影响。一般情况,使用?.的场合最好不要使用括号。

// 不管animal对象是否存在,都会执行.name
(animal?.cat).name;
// 等于
(animal === undefined || animal === null ? undefined : animal.cat).name;

3、空值合并运算符

 空值合并运算符(??)是一个逻辑运算符,与 || 运算符类似,当 ?? 运算符左侧返回 null 或 undefined 时,则返回 ?? 操作符右侧的内容。

与 || 运算符不同的是, || 运算符左侧返回 假 值时,返回右侧内容。?? 运算符只有左侧返回 null 或 undefined 时才返回右侧内容。

基本用法

 举个例子:开发者的需求是,只要属性值为 null 或 undefined 时,就给变量一个默认值。

let cat = {
  name: "",
};
// 使用 || 运行算符,name属性的值是 "" 、false 、0 、NaN 的时候,默认值也会生效
let name = cat.name || "Tom";
console.log(name); // Tom
// 使用 ?? 运算符,完美解决需求
let name1 = cat.name ?? "Tom";
console.log(name1); // ""
// 删除 name 属性
delete cat.name;
console.log(cat.name); // undefined
let name2 = cat.name ?? "Tom";
console.log(name2); // Tom

与 ?. 一起使用

 配合可选链(?.)一起使用,为 null 或 undefined 的值设置默认值。

// 配合可选链一起使用
let cat = {};
let name = cat?.name ?? "Tom";
console.log(name); // Tom

短路

与 || 和 && 运算符相似,左侧表达式不为 null 或 undefined 时,不对右侧表达式进行运算。

function a() {
  console.log("我是a函数");
  return false;
}
function b() {
  console.log("我是b函数");
  return undefined;
}
function c() {
  console.log("我是c函数");
  return "c";
}

console.log(a() ?? c());
// 依次打印 我是a函数  false
// a() 返回 false, 既不是 null 也不是 undefined
// 所以右侧表达式没有执行

console.log(b() ?? c());
// 依次打印了 我是b函数 、 我是c函数 、 c
// b() 返回 undefined,所以左右两侧表达式都执行了

与 || 或 && 一起使用

?? 本质上是逻辑运算符,但是 ?? 和 || 和 && 运算符 的优先级没有被定义,现在的规则是,如果多个逻辑运算符一起使用,必须用括号指定优先级,否则会报错。

left && middle ?? right
left ?? middle && right
left || middle ?? right
left ?? middle || right
// SyntaxError
// 上边4个表达式全部报错
// 用括号指定优先级
console.log((undefined && null) ?? "Tom"); // Tom
console.log(undefined && (null ?? "Tom")); // undefined
console.log((undefined ?? null) && "Tom"); // null
console.log(undefined ?? (null && "Tom")); // null
console.log((undefined || null) ?? "Tom"); // Tom
console.log(undefined || (null ?? "Tom")); // Tom
console.log((undefined ?? null) || "Tom"); // Tom
console.log(undefined ?? (null || "Tom")); // Tom

4、逻辑赋值运算符

ES2021 引入了三个新的逻辑赋值运算符(logical assignment operators),将逻辑运算符与赋值运算符进行结合。

基本用法

let name = "";
// 或赋值运算符
name ||= "||Tom";
// 等同于
name || (name = "||Tom");

// 与赋值运算符
name &&= "&Tom";
// 等同于
name && (name = "&Tom");

// 逻辑空赋值运算符
name ??= "??Tom";
// 等同于
name ?? (name = "??Tom");

这三个运算符 ||= 、&&= 、??=,相当于先进行左侧逻辑运算,然后根据运算结果再进行赋值运算。

用途:为属性设置默认值。

let cat = {
  name: "",
};
// 如果cat对象的name属性为逻辑假,则赋值为 Tom
cat.name ||= "Tom";
// 如果cat对象的age属性不存在,则赋值为 1
cat.age ??= 1;
console.log(cat); // {name: 'Tom', age: 1}

另一个例子:

// 旧写法
function setData(opts) {
  opts.name = opts.name ?? "Tom";
  opts.age ?? (opts.age = 1);
}
// 新写法
function setData(opts) {
  opts.name ??= "Tom";
  opts.age ??= 1;
}

很明显,新写法比旧写法更紧凑。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值