ES7
1、Array.prototype.includes
includes
方法用来检测数组中是否包含某个元素,返回布尔类型值。
indexOf
存在返回下标,不存在返回-1。
let fruits = ['apple','banana']
console.log(fruits.includes('apple')) // true
console.log(fruits.includes('strewberry')) // false
2、指数操作符
**
实现幂运算,相当于Math.pow
ES8
1.async 和 await
可以让异步代码像同步代码一样
异步编程解决方案:callback回调函数,生成器函数generator、Promise、async 和 await
- async函数
- 返回值为Promise对象
- Promise对象的结果由async函数执行的返回值决定
- 返回非Promise类型,状态为resolved
- 抛出错误,状态为rejected
- 返回是Promise类型,状态为该Promise的状态
async function fn(){
return 'a'
}
const result = fn()
console.log(result) // promise对象
- await表达式
- 必须放在async函数中
- 右侧表达式一般为promise对象
- 返回的是promise成功的值
- await的promise失败了,就会抛出异常,需要通过
try...catch
捕获处理
const p = new Promise((resovle,reject)=>{
reject('失败了')
})
async function main(){
try{
let result = await p
console.log(result)
}catch(e){
console.log(e) // 失败了
}
}
- async与await结合读取文件内容
const fs = require('fs')
function readFile1(){
return new Promise((resolve,reject)=>{
fs.readFile('./file1.txt',(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
}
function readFile2(){
return new Promise((resolve,reject)=>{
fs.readFile('./file2.txt',(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
}
function readFile3(){
return new Promise((resolve,reject)=>{
fs.readFile('./file3.txt',(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
}
async function main(){
let file1 = await readFile1()
let file2 = await readFile2()
let file3 = await readFile3()
console.log(file1.toString()) // 文件1的内容
}
main()
- async与await结合发送Ajax请求
// 发送ajax请求
function sendAjax(url){
return new Promise((resolve,reject)=>{
const xhr = new XMLRequest()
xhr.open('GET',url)
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && x.status < 300){
resolve(x.response)
}else{
reject(x.status)
}
}
}
})
}
async function main(){
let result = await sendAjax('url')
console.loog(result)
}
main()
2、对象方法扩展
Object.values
:获取对象所有的值
Object.entries
:返回数组 每一个成员又是数组 第一个元素是键 第二个元素是值
Object.getOwnPropertyDescriptors
:获取对象属性的描述对象
const student={
name:'xiaoming',
age:18
}
// keys 获取对象所有的键名
console.log(Object.keys(student)) // [name,age]
// values 获取对象所有的值
console.log(Object.values(student)) // 0 xiaoming 1 18
// entries 返回数组 每一个成员又是数组 第一个元素是键 第二个元素是值
console.log(Object.entries(student)) // [[key,value],[key,value]]
// 创建Map
const m = new Map(Object.entries(student))
console.log(m)
// getOwnPropertyDescriptors 获取对象属性的描述对象
// 作用:深层次对象克隆
console.log(Object.getOwnPropertyDescriptors(studnet)) // {name{},age{}}
// 创建对象Object.create(原型对象,描述对象)
const obj = Object.create(null,{
name:{
// 设置值
value:'xiaoming'
// 属性特性
writable:true // 写
configurable:true // 删
enumerable:true // 编辑
}
})
ES9
1、扩展运算符和rest参数
ES6:针对参数
ES9:对象
// rest参数
function connect(host,port,...user){
console.log(host) // 127.0.0.1
console.log(user) // {username:'',password:''}
}
connect({
host:'127.0.0.1',
port:3306,
username:'root',
password:'root'
})
// 扩展运算符
const student1 ={
name1:'xiaoming'
}
// ...studnet1 => name:'xiaoming'
const student2 ={
name2:'xiaoli'
}
const student3 ={
name3:'xiaozhang'
}
const student = {...student1,...student2,...student}
console.log(student) // {name1:'xiaoming',name2:'xiaoli'}
2、正则扩展
- 命名捕获分组
(?<name>)
let str = '<a href="http://www.atguigu.com">尚硅谷</a>'
// 提取url和标签文本
const reg = /<a href='(.*)'>(.*)</a>/
// 执行
const result = reg.exec(str)
console.log(result) // [匹配的结果,第一个(.*),第二个(.*)]
console.log(result[1]) // http://www.atguigu.com
console.log(result[2]) // 尚硅谷
let str = '<a href="http://www.atguigu.com">尚硅谷</a>'
const reg = /<a href='(?<url>.*)'>(?<text>.*)</a>/
const result = reg.exec(str)
console.log(result) // 多了groups内容 groups{url:'',text:''}
- 反向断言
// 正向断言
let str = 'abc123苹果456香蕉'
// 根据数字456后面的香蕉,判断前面是否合法
const reg = /d+(?=香)/
const result = reg.exec(str)
console.log(result) // 456
// 反向断言
let str = 'abc123苹果456香蕉'
// 根据数字前面的苹果,判断后面是否合法
const reg = /(?<=果)d+/
const result = reg.exec(str)
console.log(result) // 123
- dotAll模式
.
元字符:除换行符以外的任意单个字符
dotAll模式/s
// dotAll以前
// 提取电影名称和上映时间提取出来
let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期:1994-89-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-87-86</p>
</li>
</ul>`
//声明正则
const reg = /<li>s+<a>(.*?)</a>/
//执行匹配
const result = reg.exec(str)
console.log(result) // 肖生克的救赎
//声明正则
const reg = /<li>s+<a>(.*?)</a>s+<p>(.*?)</p>/
//执行匹配
const result = reg.exec(str)
console.log(result) // 肖生克的救赎 上映日期:1994-89-10
// .dotAll
const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/s
const result = reg.exec(str)
console.log(result) // 肖生克的救赎 上映日期:1994-89-10
const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/gs
let result
let data = []
while(result = reg.exec(str)){
console.log(result) // 肖生克的救赎 上映日期:1994-89-10 阿甘正传 上映日期:1994-87-86
data.push({title:result[1],time:result[2]})
}
console.log(data) // [{title:'',time:''},{}]
ES10
1、Object.fromEntries
Object.fromEntries
将二维数组或Map对象转换为对象
// 二维数组
const result = Object.fromEntries([
['name','xiaoming'],
['age',19]
])
console.log(result) //{name:'xiaoming',age:19}
// Map对象
const m = new Map()
m.set('name','xiaoming')
const result = Object.fromEntries(m)
console.log(result) //{name:'xiaoming'}
ES8:Object.entries
将一个对象转换为二维数组
const arr = Object.entries({
name:'xiaoming'
})
console.log(arr) // [[name,'xiaoming']]
2、字符串扩展方法trimStart和trimEnd
trimStart
:清除字符串左侧空白
trimEnd
:清除字符串右侧空白
3、数组扩展方法flat和flatMap
flat
:将一个多维数组转化为低维数组
flatMap
:map+flat,map的结果是多维数组的可以返回低维数组
// flat
// 二维->一维
const arr = [1,2,3,[4,5,6]]
console.log(arr.flat()) // [1,2,3,4,5,6]
// flat(n) n表示深度
// 三维->一维
const arr = [1,2,3,[4,5,6,[7,8,9]]]
console.log(arr.flat(2)) // [1,2,3,4,5,6,7,8,9]
// map
const arr = [1,2,3,4]
const result = arr.map(item => [item * 10])
console.log(result) // [[10],[20],[30],[40]]
// flatMap
const arr = [1,2,3,4]
const result = arr.flatMap(item => [item * 10])
console.log(result) // [10,20,30,40]
4、Symbol.prototype.description
description
:获取Symbol的描述字符串
let s = Symbol('apple')
console.log(s.description) // apple
ES11
1、私有属性
class Person{
// 公有属性
name;
// 私有属性
#age;
#weight;
// 构造方法
constructor(name,age,weight){
this.name = name
this.#age = age
this.#weight = weight
}
intro(){
console.log(this.#age)
}
}
const girl = new Person('xiaohong',18,'45kg')
console.log(gril) //Person{name:'xiaohong',age:18,weight:'45kg'}
console.log(gril.#age) // SyntaxError Private field #age must be declard in an enclosing class
girl.intro() // 18
2、Promise.allSettled
接收Promise的数组
返回Promise对象。状态永远为成功,值是Promise数组中的结果和结果状态
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('商品数据-1')
},1000)
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('商品数据-2')
},1000)
})
// allSettled
const result = Promise.allSettled([p1,p2])
console.log(reslut) // resovled [{},{}]
// all 状态:传入参数都成功才成功
// 有一个rejected,状态为rejected,值为出错Promise的值
// 都resolved,状态为resolved,值为成功的Promise的数组
const result Promise.all([p1,p2])
3、String.prototype.mathAll
得到正则批量匹配的结果
// 提取电影名称和上映时间提取出来
let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期:1994-89-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-87-86</p>
</li>
</ul>`
//声明正则
const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/sg
const result = str.matchAll(reg)
console.log(result) // 可迭代对象 存在next()方法
for (let v of result){
console.log(v)// 肖生克的救赎 上映日期:1994-89-10 阿甘正传 上映日期:1994-87-86
}
const arr = [...reslut]
console.log(arr) // []
4、可选链操作符
?.
:对象类型的参数深度深
function main(config){
const dbHost = config && config.db && config.db.host // 参数判断,不传入参数报错
const dbHost = config?.db?.host // 可选链操作符
console.log(dbHost) // 192.168.1.100
}
main({
db:{
host:'192.168.1.100',
username:'root'
}
cache:{
host:'192.168.1.200',
username:'admin'
}
})
5、动态import
按需加载
const btn = document.getElementById('btn')
btn.onclick = function(){
import('./hello.js').then(module => {
module.hello()
})
}
6、BigInt类型
n
:大数值运算
let n = 123n;
console.log(n, typeof(n))// 123n bigint
let n = 123
console.log(BigInt(n)) // 123n
console.log(BigInt(1.2)) // RangeError 报错
let max = Number.MAX_SAFF_INTEGER
console.log(max + 1) // +1
console.log(max + 2) // +1
console.log(BigInt(max)+1)// 报错
console.log(BigInt(max) + BigInt(1)) // +1
console.log(BigInt(max) + BigInt(2)) // +2
7、绝对全局对象globalThis
忽略环境,始终指向全局对象
console.log(globbalThis) // window