关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

运算符:指数-链判断-Null判断-逻辑赋值

发布时间:2023-06-29 22:00:21

指数运算符

// 2 * 2 console.log(2 ** 2); // 4 // 2 * 2 * 2 * 2 console.log(2 ** 4); // 16

   

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

console.log(2 ** 3 ** 2); // 512 // 2 ** (3 ** 2) // 2 ** 9 // 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2

   

指数运算符可以与等号结合,变成赋值运算符 **=

let a = 2 a **= 4 console.log(a) // 16

   

这里相当于是 a = 2 ** 4


链判断运算符

在一段业务逻辑中,经常需要获取对象内的某个属性,该属性在某些场景下可能是不存在的,所以需要判断一下。

在读取对象的深层属性时,安全的写法需要层层判断,避免报错。

let data = {  user:{  goods : {  num : 100  }  } }

   

错误写法:不安全,因为直接读取对象深层的值,前面的值(user、goods)一但不存在就会报错。

// 错误写法:不安全 let num = data.user.goods.num || 0

   

正确写法:层层判断,如果其中有一环不存在就立马返回

// 正确的写法,层层判断,data存在,并且data.user存在....其中有一项不存在则返回0 let num2 = data && data.user && data.user.goods && data.user.goods.num || 0 console.log(num2); // 100

   

三元表达式:正确写法,层层判断,直到找到最后一层

let num3 = data ? data.user ? data.user.goods ? data.user.goods.num ? data.user.goods.num : 0 : '暂无商品' : '用户不存在' : [] console.log(num3); // 100

   

但是这种写法非常麻烦,需要层层判断,因此es2020引入了"链判断运算符"。

链判断运算符:语法:?.

链判断运算符用来简化上面的写法,如果其中有一项不满足则返回右侧的值

let num4 = data?.user?.goods?.num || 0 console.log(num4); // 100

   

链判断运算符可以判断对象内的函数是否存在,如果存在就立即执行,不存在则返回undefined

let data2 = {  chains(){ return '存在'}  } console.log(data2.chains?.()); // 存在 console.log(data2.chains2?.()); // undefined

   

注意:普通函数是无法通过链判断运算符判断是否存在的,如果不存在会直接报错

function chains(){  return '存在' } console.log(chains?.()); // 存在 // console.log(chains2?.()); // 不存在 报错

   

链判断运算符的几个使用方法

let w = 'hello' let data3 = {  [w] : 'world', // 表达式键名  name : "东方不败", // 普通属性  sayHi(){ return 'hello' } // 对象内函数 } console.log(data3?.[w] || 'default'); // world console.log(data3?.name || 'default'); // 东方不败 console.log(data3.sayHi?.()); // hello console.log(data3.sayHi2?.()); // undefined console.log(data3?.sayHi?.()); // hello

   

链判断运算符其实有一个短路机制,如果条件不满足则终止执行。

以下场合使用链判断运算符会报错:

1、构造函数

2、链判断运算符右侧有模板字符串

3、链判断运算符左侧是 super

4、链运算符用于赋值运算符左侧

// 构造函数 报错 new a?.() // 右侧有模板字符串 a?.`${w}`  // 左侧是super super?.() // 右侧有赋值 a?.b = 100

   

注意:链运算符右侧如果是数字会失效,会被解析成三元运算符.会被解析成数字小数点

let num5 = {  1 : 100 } console.log(.123); // 0.123 console.log(num5?.1 : undefined); // 这里实际上被解析为num5 ? .1 : undefined,变成了三元运算符

   


Null判断运算符

在读取对象属性的时候,判断某个属性是否存在,如果属性的值是nullundefined时,给该属性一个默认值,常见的做法是用||运算符判断是否存在,不存在则返回右侧的值。

|| 运算符存在隐式转换,0、null、undefined、空字符串都会被转换为false

let n = {  user : '东方不败',  status : 0 } let u = n.user || '用户不存在' let u2 = n.user2 || '用户不存在' console.log(u); // 东方不败 console.log(u2); // 用户不存在  let u3 = n.status || '不存在' console.log(u3); // 不存在

   

||运算符更适合判断属性是否为假(false),而不是null、undefined

es2020提供了新的null判断运算符,语法:??

它的行为跟 || 运算符基本相同,唯一的不同是它没有隐式转换,只有左侧的值为nullundefined时才会返回右侧的值。

let judge = {  user : "东方不败",  num : 0,  status : false,  em : null } let back = judge.user ?? '不存在' let back2 = judge.num ?? '不存在' let back3 = judge.status ?? '不存在' let back4 = judge.em ?? '不存在' console.log(back); // 东方不败 console.log(back2); // 0 console.log(back3); // false console.log(back4); // 不存在

   

多个逻辑运算符一起使用,必须用括号表明优先级,否则报错

// 报错 a && b ?? c a ?? b && c a || b ?? c a ?? b || c

     

// 正确的写法, 加上括号表明优先级 (a && b) ?? c; a && (b ?? c); (a ?? b) && c; a ?? (b && c); (a || b) ?? c; a || (b ?? c); (a ?? b) || c; a ?? (b || c);

   


逻辑赋值运算符

es2021引入三个逻辑赋值运算符,将逻辑运算符和赋值运算符结合

let x = 0 let y = 5 let z = x ||= y let z2 = x ??= y let z3 = x &&= y console.log(z); // 5 console.log(z2); // 5 console.log(z3); // 5 console.log(x); // 5

   

其实这个逻辑赋值运算符和逻辑运算符是一样的,只不过看起来更直观

逻辑运算符:左侧的值不存在就把右侧的值赋值给该对象

逻辑赋值运算符:左侧的值不存在就把右侧的值等于左侧,将左侧的值赋值给该对象

注意:逻辑赋值运算符会更改被赋值的原始值,上述案例中,右侧的y赋值给了左侧的x,左侧的x=5,所以下面的??运算符判断x=5,导致并没有走右侧的y逻辑赋值运算。

let b = 0 let m = 5 let f = b ??= m console.log(f); // 0

   


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果觉得这篇文章对你有帮助,欢迎点亮一下star哟


/template/Home/leiyu/PC/Static