携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
类的声明
ES6中引入了Class这个概念,可以通过关键字class定义一个类
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
show(){
console.log(`name为${this.name}-age为${this.age}`)
}
}
const person = new Person("李四",11)
person.show()
而在ES13中出现比这种更加简洁的写法,让我们一起来看一看
以前我们要定义类字段必须要在constructor方法中声明,现在我们可以在顶层声明
class Person{
name = "张三";
age = 11;
}
const person = new Person()
console.log(person.name) // 张三
同时这种方式定义的属性可作为一个公共属性,即类可以直接调用,实例也可以调用
class Person{
name = "张三";
age = 11;
constructor(grade){
this.grade = grade;
}
}
// console.log(Person.#name)
const person = new Person("3年级")
//类不可以直接调用在constructor中定义的属性
console.log(Person.grade); // undefined
console.log(Person.name) // 张三
console.log(person.grade)//3年级
console.log(person.name);//张三
私有属性
使用#为类添加私有属性
class Person{
#name = "张三";
age = 11;
}
const person = new Person()
console.log(person.name)//undefined
console.log(person.#name)//这里会提示一个语法错误
私有类属性
通过static和 # 添加一个类属性
class Person{
static #name = "张三";
age = 11;
}
console.log(Person.name)//undefined
静态代码块
在加载类就执行一次的静态代码块
class Person {
static name = "张三";
static age = 11;
constructor(grade) {
this.grade = grade;
console.log("grade", this.grade) // 3年级
}
static {
console.log("name", this.name) // 张三
}
static {
console.log("age",this.age) // 11
}
#show() {
console.log(this.grade)
}
}
// console.log(Person.#name)
const person = new Person("3年级")
且执行顺序先于constructor执行,多个静态代码块按顺序执行
in运算符
in运算符可以用于检查指定的属性或者字段在对应的对象或者类中,是则返回true,反之为false
class Person {
#name = "张三";
age = 11;
constructor(grade) {
this.grade = grade;
}
hasAge() {
return "age" in this
}
hasName() {
return #name in this
}
}
const person = new Person("3年级")
console.log(person.hasAge());// true
console.log(person.hasName());// true
可以看见。类私有属性照样可以检测。同时可以区分出不同类的同名字段
class Person {
#name = "张三";
age = 11;
hasName() {
// console.log(this.#name)
return #name in this
}
}
class Person1{
#name = "李四"
hasName(){
// console.log(this.#name);
return #name in this
}
}
const person = new Person()
const person1 = new Person1()
console.log(person.hasName()); //true
console.log(person.hasName.call(person1)) // false
console.log(person1.hasName()) // true
at()方法
在正常情况下,我们需要访问数组其中的某一项,一般是这样数组名[索引],这里我们只能访问数组的n-1个数组成员,访问索引之外的就会返回undefined,如:
const arr = [1,2,3]
console.log(arr[1]); // 2
console.log(arr[-1]) // undefined
如果这里我们使用at()方法就会有不一样的表现力.
const arr = [1,2,3]
console.log(arr[1]); // 2
console.log(arr[-1]) // undefined
console.log(arr.at(-1)); // 3
可以看见,不仅取出来力,而且刚好是倒数第一个数,再试试-2
console.log(arr.at(-2)); //2
得出一个结论:这样的传入的是一个大于等于0的数,那么和直接访问没有区别,如传入的是一个负数,访问的就是索引为 length + n (n是参数)的数,也可以理解为访问的是倒数第n个元素。除数组外,字符串和TypeArray也有同样的方法。
await运算符
在ES2017中加入新的语法糖就是async/await,用此来简化Promise的使用,await运算符用于暂定执行,直到Promise被完成(成功或者失败皆可)。以前我们只能用await只能在async声明过的函数中使用,要不然就会报错,如:
function getName() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("张三")
}, 1000)
})
}
let name;
const setName = async () => {
name = await getName();
console.log("前面的", name);
}
setName()
await getName()//await is only valid in async functions and the top level bodies of modules
要想解决这个问题,其中一个的解决方案就是开启顶层await,需要注意的是顶层await只在ES模块中生效,如果在node环境下,需要在package.json中显示开启"type":"module",这段代码可以看出效果:
function getName() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("张三")
}, 1000)
})
}
let name;
const setName = async () => {
name = await getName();
console.log("前面的", name); // 前面的 张三
}
setName()
const nextName = await getName()
console.log("后面的",nextName); // 后面的 张三
RegExp匹配索引
exec可以帮助我们获取到给定字符串匹配到RegExp对象中的起始索引。如:
const str = "这是一个新的特性"
const reg = new RegExp("新的");
const exec = reg.exec(str);
console.log(exec);//[ '新的', index: 4, input: '这是一个新的特性', groups: undefined ]
index就是它的起始索引。我们可以在RegExp的第二个参数加一个d,可以得到匹配字符串的起始和结束索引。如:
const str = "这是一个新的特性"
const reg = new RegExp("新的","d");
const exec = reg.exec(str);
console.log(exec);//[
'新的',
index: 4,
input: '这是一个新的特性',
groups: undefined,
indices: [ [ 4, 6 ], groups: undefined ]
]
indices数组的第一个成员就是起始和结束索引的数组。
Object.hasOwn()方法
在这个新特性出来之前,我们是使用Object.prototype.hasOwnProperty()方法来检测对象中是否含有特定的属性。
因为该方法在Object的原型对象上,我们完全可以重新修改或者定义一个新的该方法,并且覆盖掉它,使其与不一样的行为。
解决这个问题的其中一个方案就是使用Object.hasOwn()方法,该方法是直接定义在Object的静态方法。该方法接受对象和属性作为参数。如果对象中包含了属性就返回true,反之为false。如:
const obj = {
title:"这是一个新的特性"
}
console.log(Object.hasOwn(obj,"title"));// true
错误原因
使用throw new Error可以通过第二个参数加入cause属性来指定错误原因。这里就是简单模拟一下,具体场景会更加复杂。
function cause() {
throw new Error("这是一个错误", { cause: "使用cause" })
}
try {
cause()
} catch (error) {
console.log(error);
console.log(error.cause) // 使用cause
}
end
瑞思拜