微信图片_20211214161810.png

空值合并运算符

  • 获取对象的属性的时候,我们经常需要为null/undefined的属性设置默认值。现在我们都是使用||运算符来处理,例如
  1. let userInfo = {};
  2. let name = userInfo.name || 'Lucky';
  • 但是false,0,’ ‘值被替换掉,导致运算结果不准确
  • 空合并运算符 (??) 是一个逻辑运算符,当其左侧操作数为空(null)或未定义(undefined)时返回其右侧操作数,否则返回其左侧操作数。
  1. const foo = null ?? 'default string';
  2. const baz = 0 ?? 42;
  3. console.log(foo); // default string
  4. console.log(baz); // 0

.前边加? 可选链运算符

  • 我们有时候为了访问深层嵌套的属性,一不小心就会报undefined的错,需要写一个很长的&&链去检查每个属性是否存在,代码如下
  • 业务代码中经常会遇到这样的情况,a对象有个属性b,b也是一个对象有个属性c,
  • 我们需要访问c,经常会写成a.b.c,但是如果f不存在时,就会出错
  1. const a = {
  2. b: {
  3. c: 123,
  4. }
  5. }
  6. console.log(a.b.c); // 123;
  7. console.log(a.f.c); // f不存在所以会报错
  • ECMAScript2020定义可选链运算符解决该问题,通过在.之前添加一个?将键名变成可选
  1. let person = {};
  2. console.log(person?.profile?.age ?? 18); // 18
  • 可选链运算符也可以运用在方法上
  1. let age = getUserInfo?.().data?.info?.age;

String.prototype.replaceAll

  • String 原型上的 replaceAll() 函数允许替换子字符串的所有实例,而无需使用正则表达式。
  • 如果在字符串上使用了 replace(),它只会替换该值的第一个实例。
  • 另一方面,replaceAll() 提供替换该值的所有实例的功能
  • 在字符串操作里面我们在某些业务场景下需要做的操作是去替换字符串里面的某些内容,比如字符串aabbccbbdd中要求删掉字符b,
  • 那么一般能想到的有两种方法,第一种是用正则去删除,另一种是使用for循环遍历字符。
  1. // 使用正则
  2. let str = 'aabbccbbdd'
  3. console.log(str.replace(/b/g,''))
  4. // 循环遍历
  5. let str = 'aabbccbbdd'
  6. let res = ''
  7. for (let i = 0, len = str.length; i < len; i++) {
  8. if(str[i] != 'b'){
  9. res += str[i]
  10. }
  11. }
  12. console.log(res)
  • 使用replaceAll
  1. let str = 'aabbccbbdd'
  2. let res = str.replaceAll('b','') // 'aaccdd'
  • 使用replace()
  1. let str = 'aabbccbbdd'
  2. console.log(str.replace('b','0')) //'aa0bccbbdd'

数字分隔符

  • 数字分隔符允许您在文字数字的数字之间添加下划线,这使它们更具可读性。
  • 当文件被解析时,这些下划线将被自动去除。请参阅以下代码片段以了解如何使用数字分隔符。
  1. let n1 = 1_000_000_000;
  2. console.log(n1); // This will print: 1000000000
  3. let n2 = 1_000_000_000.150_200
  4. console.log(n2); // This will print: 1000000000.1502
  5. let n3 = 0x95_65_98_FA_A9
  6. console.log(n3); // This will print: 641654651561
  7. let n4 = 155_326_458_156_248_168_514n
  8. console.log(n4); // This will print: 155326458156248168514n

- 注意,下划线不能连续,也不能放在开头和结尾,放在开头,就变成字符串了,会被当成变量名,放在结尾会直接报语法错误

逻辑赋值运算符

逻辑或分配(|| =)

  • x || = y:仅当 x 为假时,才将 y 赋值给 x。如果 x 是真,则不会进行赋值运算。
  1. //简写
  2. x ||= y
  3. //全写
  4. x || (x = y)
  5. //前置条件
  6. x = 0, y = 10
  7. //根据前置条件运行的结果
  8. 10

逻辑与分配(&& =)

  • x && = y:仅当 x 为真时,才将 y 赋值给 x。如果 x 为假,则不会进行赋值运算。
  1. //简写
  2. x &&= y
  3. //全写
  4. x && (x = y)
  5. //前置条件
  6. x = 1, y = 11
  7. //根据前置条件运行的结果
  8. 11

逻辑空分配(?? =)

= x ?? = y:仅当 x 为 null 或 undefined 时,才将 y 分配给 x。如果 x 既不是 null 也不是 undefined 则不会进行赋值。

  1. //简写
  2. x ??= y
  3. //全写
  4. x ?? (x = y)
  5. //前置条件
  6. x = null, y = 12
  7. //根据前置条件运行的结果
  8. 12

异步加载模块 - import()

  • 有时候我们需要动态加载一些模块,这时候就可以使用 import() 了
  1. // logger.js
  2. export default {
  3. log: function() {
  4. console.log(...arguments);
  5. }
  6. };
  1. import('./logger.js')
  2. .then((module)=>{
  3. module.default.log('p9');
  4. })
  • 当然,也可以使用await进行等待
  1. let module = await import('./logger.js');

通过 # 给 class 添加私有变量

  1. class Counter{
  2. #number = 10
  3. increment(){
  4. this.#number++;
  5. }
  6. getNum(){
  7. return this.#number;
  8. }
  9. }
  10. const counter = new Counter();
  11. counter.increment();
  12. console.log(counter.getNum()) // 11
  13. console.log(counter.#number) // SyntaxError