.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);