ECMAScript 2021逻辑赋值操作符详解

吐槽君 分类:javascript

ES2021版本新特性

JavaScriptES2021提出了许多有趣的新特性。每年添加到ES的新特性都会历经四个阶段,当特性处于第四阶段时即可被正常使用。目前已经完成提案(Finished Proposals)的有如下特性:

  • String.prototype.replaceAll
  • Promise.any
  • WeakRef(弱引用)
  • 逻辑赋值运算符(Logical Assignment Operators)
  • 数字分隔符(Numeric separators)

本文主要详讲逻辑赋值运算符

目的

结合逻辑运算符和赋值表达式的表现,为了让代码更加简洁,并且更加具有可读性,使用了有一段时间了,实用性还是很高的。

使用

使用前确保浏览器或者打包编译工具能够支持,babel 有提供了相关的插件。

npm install --save-dev @babel/plugin-proposal-logical-assignment-operators

{
  "plugins": ["@babel/plugin-proposal-logical-assignment-operators"]
}
 

逻辑复制运算符即将普通的逻辑运算(?? 、|| 和 &&)和赋值表达式结合使用。

1、带有??运算符的逻辑赋值运算符(??=)

空值合并运算符(??)为 ES2020 的新特性,即仅当 LHS(左侧,Left-hand Side) 为 undefined 或者 null , RHS(右侧,Right-hand Side) 变量才会赋值给 LHS 变量。如下例:

let flag; // undefined
const val = 'test';
console.log(flag ?? val);  // test
flag = null;
console.log(flag ?? val);  // test
flag = false;
console.log(flag ?? val);  // false
flag = 'flag';
console.log(flag ?? val);  // 'flag'
 

回到 ES2021 ,结合上面的空值合并运算符来查看??=的表现。

let value1; // undefined
let value2 = '2';
value1 ??= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2

// value1赋值为null
value1 = null;
value1 ??= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2

// value1赋值false
value1 = false;
value1 ??= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=false, value2=2

// value1赋值'1'
value1 = '1';
value1 ??= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=1, value2=2
 

综上所述,当且仅当 value1 为 undefined 或者 null 时,value1 变量会被赋值 value2 变量的值,而当 value1 为其他值时,value1 的值则不变。在这其中,value2 变量值时不变的,而 value1 变量值根据自身值来决定是否被赋值。

以上代码转成 ES5 如下:

"use strict";

var _value, _value2, _value3, _value4;

let value1; // undefined

let value2 = '2';
(_value = value1) !== null && _value !== void 0 ? _value : value1 = value2;

// value1赋值为null
value1 = null;
(_value2 = value1) !== null && _value2 !== void 0 ? _value2 : value1 = value2;

// value1赋值false
value1 = false;
(_value3 = value1) !== null && _value3 !== void 0 ? _value3 : value1 = value2;

// value1赋值'1'
value1 = '1';
(_value4 = value1) !== null && _value4 !== void 0 ? _value4 : value1 = value2;
 

2、带有 || 运算符的逻辑赋值运算符(||=)

同理,仅当 LHS 值为假时,才将 RHS 变量值赋给 LHS 变量。

let value1; // undefined
let value2 = '2';
value1 ||= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2

// value1赋值为null
value1 = null;
value1 ||= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2

// value1赋值false
value1 = false;
value1 ||= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2

// value1赋值'1'
value1 = '1';
value1 ||= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=1, value2=2
 

||= 与 ??= 在于当 LHS 变量值为 false 时,便会被赋值 RHS 变量值,这个与 || 操作符本质有关。

以上代码转成 ES5 如下:

"use strict";

let value1; // undefined

let value2 = '2';
value1 || (value1 = value2); 

// value1赋值为null
value1 = null;
value1 || (value1 = value2);

// value1赋值false
value1 = false;
value1 || (value1 = value2);

// value1赋值'1'
value1 = '1';
value1 || (value1 = value2);
 

3、带有 || 运算符的逻辑赋值运算符(&&=)

同理,仅当 LHS 值为真时,才将 RHS 变量值赋给 LHS 变量。若 LHS 值为假,则 LHS 变量值没有变化。

let value1; // undefined
let value2 = '2';
value1 &&= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=undefined, value2=2

// value1赋值为null
value1 = null;
value1 &&= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=null, value2=2

// value1赋值false
value1 = false;
value1 &&= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=false, value2=2

// value1赋值'1'
value1 = '1';
value1 &&= value2;
console.log(`value1=${value1}, value2=${value2}`);   //  value1=2, value2=2
 

以上代码转成 ES5 如下:

"use strict";

let value1; // undefined

let value2 = '2';
value1 && (value1 = value2);

// value1赋值为null
value1 = null;
value1 && (value1 = value2);

// value1赋值false
value1 = false;
value1 && (value1 = value2);

// value1赋值'1'
value1 = '1';
value1 && (value1 = value2);
 

总结

ES2021还有其他好玩的新特性,本文主要讲了逻辑运算操作符,有兴趣的同学可以去看看其他特性。下面附上ES
的文档和babel链接。

参考链接:

babeljs.io/docs/en/bab…

github.com/tc39/propos…

回复

我来回复
  • 暂无回复内容