ES12的一些新特性

565 阅读4分钟

一、前言

鉴于我之前的一篇关于内存释放、垃圾回收机制的一篇文章 weakMap、weakSet、weakRef、FinalizationRegistry傻傻分不清楚提到了FinalizationRegistryweakRef这些ES12的类,然后就心血来潮的去再看了一下ES12的别的特性。

毕竟ES12是ECMA协会在2021年6月发行的一个版本,因为是ECMAScript的第十二个版本,所以也称为ES12,距今已经好几年了。

顺便整理一下常用的ES12的一些特性或方法。

二、replaceAll

replaceAll() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,该函数会替换所有匹配到的子字符串。

语法

const newStr = str.replaceAll(regexp|substr, newSubstr|function)

参数值

regexp|substr

必传 用来规定子字符串或要替换的模式的 RegExp 对象。
请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。当使用一个 regex 时,您必须设置全局g标志, 否则,它将引发 TypeError:"必须使用全局 RegExp 调用 replaceAll。"

newSubstr|function

必传 一个字符串值。规定了替换文本或生成替换文本的函数。

var str = "hello world";
// replace
str.replace(/o/g, "a); // hella ward
// replaceAll
str.replaceAll("o", "a"); // hella warld

三、逻辑赋值操作符

逻辑赋值操作符将逻辑操作(&&||??)与赋值表达式组合在一起。

&&||??

带有&&的逻辑赋值操作符

let x = 1;
let y = 2;
x &&= y;
console.log(x); // 2

x &&= y 等价于 x && (x = y)

或者等价于

if(x) {
  x = y
}

因为x是一个真值,所以它被赋值为y,即2

同理:

x ||= y; 
x || (x = y); 
x ??= y; 
x ?? (x = y);

带有??的逻辑赋值操作符

?? 在 JS 中专门检查一个值是否为 nullundefined

let a;
let b = a ?? 5;
console.log(b); // 5

let b = a ?? 5,如果a的值为nullundefined??求值并赋值给b

现在考虑??==

let x;
let y = 2;
x ??= y;
console.log(x); // 2

x ??= y 等价于 x = x ?? (x=y)

数字分隔符

它允许我们在数字之间添加下划线(_)字符,使数字更具可读性。

例如

const num = 100000000

被0的数量所迷惑

分隔符解决这个问题:

const num = 100_000_000

分隔符可以用于数字的整数部分和小数部分。

const num = 1_000_000.123_456

分隔符不仅可以用在整数和浮点数中,也可以用在二进制、十六进制、八进制字面量中。

分隔符也适用于BigInt数字。

const trillion = 1000_000_000_000n;
console.log(trillion.toString()); // "1000000000000"

分隔符只是为了可读性。所以,它可以放在数字内的任何地方,也不会影响该数字的值。

const amount = 178_00; 
const num =123_456_789
console.log(num) //123456789

四、 WeakRefs 与 FinalizationRegistry

在我的另一篇文章 weakMap、weakSet、weakRef、FinalizationRegistry傻傻分不清楚中,更详细的讲解了这一部分。

五、私有方法

谈到私有方法,就得先提一下class类的概念 自从JS有了类的概念之后,就可以在类中定义方法,并通过实例化之后的类进行调用,如下所示:

class Student {
  getHair() {
    console.log("张张还有好多头发")
  }
}

student= new Student();
student.getHair();
//运行结果 : "张张还有好多头发"

如果我们不希望getHair()方法直接暴露给外部使用,也就是说希望getHair()是一个私有方法毕竟发量是不能轻易让人知道的=。=,那么只需要在方法前面加上#即可。

class Student {
  #getHair() {
    console.log("张张还有好多头发")
  }
}

student= new Student();
student.getHair();
//运行结果 : Error: student.getHair is not a function

那我们自己如何调用呢,总不能自己有多少头发自己也不能知道吧,私有方法是可以在方法内部调用的,就好比我在自己家里照镜子当然能看到自己发量了,所以只需这样

class Student {
  #getHair() {
    console.log("张张还有好多头发")
  }
 getMyHair(){
    this.#getHair();
  }
}

student= new Student();
student.getMyHair();
//运行结果 : "张张还有好多头发"

六、私有属性

上面刚说了私有方法,那么私有属性又是如何呢?在一般使用中,我们可以使用get修饰符去进行修饰,这样就可以直接通过属性名进行访问属性了

class Student {
  get Hair() {
    return 'lots of hair';
  }

}

student= new Student();
console.log(student.Hair);//lots of hair

同样,可以在属性名前面加上#,让其变成私有变量,

class Student {
  get #Hair() {
    return 'lots of hair';
  }

}

student= new Student();
console.log(student.Hair);//undefined

要想访问上述的私有属性,则可以用公有属性去调用私有属性方法:

class Student {
  get #Hair() {
    return 'lots of hair';
  }
 get myselfHair() {
    return this.#Hair
  }
}

student= new Student();
console.log(student.myselfHair);//lots of hair