ES12 新特性,纯手打!!!

101 阅读5分钟

.at访问数组

简洁说明

let arr = [1,2,3,4,5]
//下面说的是等价写法
arr.at(-1) === arr[arr.length-1]
arr.at(1) ==== arr[1]

这是做什么的?解决了什么问题?

let arr = [1,2,3,4,5]

现在我有了一个数组arr,我要访问它的最后一个元素

//使用es12新特性array.at方法
arr.at(-1)//访问结果为5
//es12之前
arr[arr.length-1]//访问结果为5

这样写更爽,更效率

class的私有属性和静态属性

私有属性

做什么的?解决了什么问题?

使用私有方法来更好的封装一个类,在我不希望别人能直接访问这个数据的时候使用私有属性

使用 # 来标记私有属性

class User{
  #name;
  age;
  constructor(name,age){
    this.#name = name;
    this.age = age;
  }
  #printf(){
     console.log('我是私有方法')
  }
 }
const user = new User('zs',18);
console.log(user)//=> User {age: 18, #name: 'zs'}
user.age //访问结果为18
user.#name//无法访问
user['#name']//无法访问
user.printf()//无法访问

间接的访问私有属性

既然都无法访问了,那存在它又有什么用呢?

我们可以使用数据代理来让别人间接的访问到它

class User{
  #name;
  age;
  constructor(name,age){
    this.#name = name;
    this.age = age;
  }
  get name(){
    //我可以在这里进行一些验证,或者操作一些其它数据
    return this.#name
  }
  set name(value){
    //我可以在这里进行一些验证,或者操作一些其它数据
    console.log(`有人修改了name,新值:${value}旧值:${this.#name}`)//yes6模板语法
    this.#name = value
  }
 }
 const user = new User('zs',18);
 user.name = '李四'//这里对name进行写入,对应class中的 set name(){}
 user.name //这里对name进行读取,对应class中的 get name(){}

静态属性

做什么的?

私有属性static不允许被继承,同时也不允许被实例化,它仅仅存在于被定义的class中

什么是继承?如何继承?

//定义一个用户,它拥有name和age属性
class User{
  constructor(name,age){//!!!user构造器,后面有用到
    this.name = name;
    this.age = age;
  }
}
//定义一个管理员 !!!继承!!! 用户这个类
//关键字 extends  super()
class Admin extends User{
    constructor(name,age,token){
        super(name,age)//!!!调用User构造器,需要注意书写位置
        this.token = token;
    }
    
}
const admin = new Admin('zs',18,'令牌')
console.log(admin)//Admin {name: 'zs', age: 18, token: '令牌'}
//可以看到,admin拥有User中的属性,这就是继承

什么是实例化

const user = new User('zs',18) //这种由模板到对象的过程叫实例化,获得的参数user叫User类的实例

定义一个静态属性 并尝试将它实例化出来

//使用static关键字来标记私有属性
class User{
    constructor(name,age){
    this.name = name;
    this.age = age;
    this.#name = '私有'+name
  }
  static printf(){
      console.log('我是私有属性,不会被继承,也不会被实例化')
      console.log(this.#name)//可以访问到私有属性
  }
}
//继承我懒得写了....好累,不能被继承就对了
const user = new User('zs',18)
console.log(user)//=>user {name: 'zs', age: 18}
//没有printf方法,因为它是c语言的(不是)因为它是静态的
User.printf()//可以被调用,它存在于User上

错误抛出

感觉大佬一眼会,新人看了也没用,我就不多赘述了.

async function fetcUserPreferences() {
  try { 
    const users = await fetch('//user/preferences')
      .catch(err => {
        throw new Error('users遍历出错', {cause: err});//看这里
      })
    }
}
fetcUserPreferences();

Object.prototype.hasOwnProperty.call() 的另一种调用方法 Object.hasOwn()

Object.prototype.hasOwnProperty.call()是什么?

使用它判断属性是实例化出来的还是后续添加的,这有两种方法

let obj = new Object();
obj.name = 'zs';
obj.hasOwnProperty('name');             // 返回 true  它是后续添加的
obj.hasOwnProperty('toString');         // 返回 false  这个方法显然是继承自 Object对象
obj.hasOwnProperty('hasOwnProperty');   // 返回 false  这个方法显然是继承自 Object对象

//以上写法并不规范,在一些场景下会出bug,需要使用下面的写法,可是下面的写法又太复杂

Object.prototype.hasOwnProperty.call(obj,'name')    //返回true 这是原型对象调用

ES12更简便的书写方法

Object.hasOwn(obj,'name'); 等价于: Object.prototype.hasOwnProperty.call(obj,'name');

let obj = new Object();
obj.name = 'zs';
Object.hasOwn(obj,'name');             // 返回 true  它是后续添加的
Object.hasOwn(obj,'toString');         // 返回 false  这个方法显然是继承自 Object对象
Object.hasOwn(obj,'hasOwnProperty');   // 返回 false  这个方法显然是继承自 Object对象

新的逻辑运算符

a ||= b
//等价于
a = a || (a = b)  // 当左边没有值时,将右边的值赋值给左边

a &&= b
//等价于
a = a && (a = b)  //当左边有值时,将右边的值赋值给左边

a ??= b
//等价于
a = a ?? (a = b)  // 当左边值为null或者undefined时,将右边的值赋值给左边

正则表达式匹配索引

我这方面知识比较薄弱,就直接贴官方的机翻代码了

目前,在 JavaScript 中使用 JavaScript Regex API 时,仅返回匹配的开始索引。但是,对于一些特殊的高级场景,这还不够。

作为这些规范的一部分,添加了一个特殊的标志 d。通过使用它,正则表达式 API 将返回一个二维数组作为名索引的键。它包含每个匹配项的开始和结束索引。如果在正则表达式中捕获了任何命名组,它将在 indices.groups 对象中返回它们的开始/结束索引, 命名的组名将是它的键。

// ✅ a regex with a 'B' named group capture
const expr = /a+(?<B>b+)+c/d;

const result = expr.exec("aaabbbc")

// ✅ shows start-end matches + named group match
console.log(result.indices);
// prints [Array(2), Array(2), groups: {…}]

// ✅ showing the named 'B' group match
console.log(result.indices.gr
oups['B'])
// prints [3, 6]
复制代码

正则表达式匹配索引原始提案,github.com/tc39/propos… indices

await等待导出

//在users.js
export const users = await fetch('/users/lists');

//在需要的地方引入
import { users } from "./users.js";
//会等待users.js中的fetch执行完毕后再引入模块,这是一个很好且直观的功能,但是需要小心使用,我们不要滥用它。
console.log(users);