目录
·ES6-class(类)的声明及继承
1.ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字去定义类,其中constructor()作为类的构造函数使用。
class Father{
constructor(name,age){
this.name = name
this.age = age
}
fun1(){
console.log('我是一个人')
}
}
class 的本质可以看作是 function,所以在类中prototype 仍旧存在,类中的方法还是定义在 prototype 上的。 所以Father类中constructor()和fun1()方法都是在prototype上的。
2.ES6中类的继承使用 extends 关键字。 在子类的构造函数中必须调用super()函数,代表父类的构造函数。(如果在子类构造函数中不调用super()函数就会报错)
class Son extends Father{
constructor(name,age,high){
super(name,age) //代表调用父类的构造函数
this.high = high
}
}
son = new Son("son",22,170)
//继承了父类Father的函数
son.fun1() //我是一个人
super ()虽然代表了父类 Father 的构造函数,但返回的是子类 Son 的实例,即 super 内部的 this 指的是 Son 的实例,因此 super() 在这里相当于 Father.prototype.constructor.call(this)。
·ES6-Promise
我们首先要知道同步任务和异步任务分别是什么?
我们知道,javascript语言是单线程机制,任务的执行分为主线程和单线程,符合事件循环模型(会详细在后续章节讲解)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。其中,DOM事件、AJAX、定时器都属于异步操作。
Promise是ES6中引入的异步编程的新解决方案,在语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
Promise接受一个回调函数作为参数,回调函数的参数是resolve、reject;其中resolve是将Promise的状态置为fullfiled(已成功),reject是将Promise的状态置为rejected(已失败)。then 方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。then方法执行后的返回值仍旧是一个新的Promise对象:
let p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('p1') //"p1"字符串作为下一个then的传入参数
},4000)
})
p1.then(value=>{
console.log(value)
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('p2')
},2000)
})
}).then(value =>{
console.log(value)
})
根据事件循环模型,在代码初始化的同时定时器就开始计时,由于p1是延迟4s输出,p2是延迟2s输出,所以回调队列中首先应该输出的是p2然后才是p1;如果要首先输出p1,然后再输出p2,不使用Promise的情况下就要进行函数嵌套,这样就会产生回调地狱问题,即代码块一个套一个,非常影响阅读和维护。在使用了Promise后,上述代码则首先输出p1 然后输出p2,很好的解决了异步编程的问题。
·ES8-async await
async 和 await可以让异步代码像同步代码一样编写。我们要注意以下几点:
1.async函数的返回值为promise对象,且promise对象的结果由async函数执行的返回值决定。
2.await必须写在async函数中。
3.await右侧表达式一般为promise对象。
4.await返回的值是promise成功的值。
5.await的promise失败就会抛出异常,需要通过try...catch捕获处理。
let p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(p1)
},4000)
})
function send(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(p2)
},2000)
})
}
async function main(){
try{
const res1 = await p1
console.log(res1)
const res2 = await send()
console.log(res2)
}
catche(e){
console.log(e)
}
}
main()
上述代码与前一部分讲述Promise的小节输出相同,先输出p1,然后输出p2。
·ES9-反向断言
反向断言的意思就是根据目标字符串的前边的字符来匹配目标字符串。例如由如下字符串:
“我是来自于前端2022班的学号为1234567的李小明”
我们要获取以上字符串中的学号信息,我们首先想到的是使用正则匹配,即正向断言:
let str = "我是来自于前端2022班的学号为1234567的李小明"
const reg = /\d+(?=的)/
const result = reg.exec(str) //1234567
我们也可以使用如下反向断言:
let str = "我是来自于前端2022班的学号为1234567的李小明"
const reg = /(?<=为)\d+/
const result = reg.exec(str) //1234567
·ES10-数组多维转低维
在ES10中,可以使用flat()方法可以对数组多维转低维:
const arr1 = [1,2,3,[4,5]]
//使用flat()函数将多维数组展成一维
console.log(arr1.flat()) //[1,2,3,4,5]
const arr2 = [1,2,3,[4,5,[6,7,8,9,10]]]
//使用flat()函数将多维数组展成一维
//flat() 函数中参数为展开的深度
//参数默认为1 flat() 等价于 flat(1)
console.log(arr2.flat()) //[1,2,3,4,5,Arry(5)]
//arr2的深度为2,若要全部展开则需要将flat()中参数置为2
console.log(arr2.flat(2)) //[1,2,3,4,5,6,7,8,9,10]
·ES11-class类的私有属性
ES11中类的私有属性通过 # 标识,且私有属性实例化对象不能直接使用,只能通过方法调用。
class Father{
#id; //私有属性
constructor(name,age,id){
this.name = name
this.age = age
this.#id = id
}
fun1(){
console.log(this.#id) //私有属性实例化对象不能直接使用,只能通过方法调用
}
}
daddy = new Father("father",36,100)
daddy.fun1() // 100
·ES11-BigInt类型
在使用js进行大数计算的时候,由于js精度限制,当数据达到一定范围以后,js的计算结果就不在正确,如下所示max取到最大安全整数后,再进行加法就不精确了,这时候我们就可以通过 ES11新特性中的 BigInt
类型来解决这一问题。
let max = Number.MAX_SAFE_INTEGER
console.log(max) //9007199254740991
console.log(max+1) //9007199254740992
console.log(max+2) //9007199254740992
console.log(BigInt(max) + BigInt(1)) //9007199254740992n
console.log(BigInt(max) + BigInt(2))//9007199254740993n
//BigInt类型中后边会带n,为了保持美观棵先将其转为string类型,这样n就消失了
console.log((BigInt(max) + BigInt(2)).toString()) 9007199254740993
·ES11-globalThis
globalThis 默认一直执行全局对象,任何时候想对全局对象进行操作,可以不用考虑当前所处环境,直接使用gloablThis对全局环境进行操作