目录
- ES7
- - includes
- - ** 幂运算
- ES8
- - async和await
- * async函数
- * await表达式
- - 对象方法扩展
- ES9
- - rest参数与spread扩展运算符
- - 正则扩展
- * 命名捕获分组
- * 正则断言
- * dotAll模式
- ES10
- - Object.fromEntries(二维数组或Map转为对象)
- - trimStart和trimEnd(去除字符串前面或后面的空格)
- - flat(多维数组转为低维数组)
- - flatMap(map函数功能 + 转换低维数组)
- - Symbol.prototype.description(获取Symbol的描述对象)
- ES11
- - 类的私有属性
- - Promise.allSettled(返回其中所有promise对象的执行结果)
- - String.prototype.matchAll(正则批量匹配)
- - 可选链操作符 ?.
- - 动态import加载
- - 新的数据类型-BigInt 大整数(用于更大的数值运算)
- - globalThis(全局对象)
ES7
- includes
includes方法用来检测数组中是否包含某个元素,返回布尔类型值
类似于indexOf,只不过indexOf当找不到元素时,返回的是-1
代码例:
// includes
const arr = ['a', 'b', 'c', 'd']
console.log(arr.includes('b')) // true
console.log(arr.includes('f')) // false
- ** 幂运算
在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
代码例:
// **
// 2的10次方
console.log(2 ** 10) // 1024
// Math.pow方法
console.log(Math.pow(2, 10)) // 1024
ES8
- async和await
* async函数
async 函数的返回值为 promise 对象
promise 对象的结果由 async 函数执行的返回值决定
代码例:
// async函数,返回结果是一个Promise对象
// 而Promise对象内的结果(状态、值)由async函数内执行的返回值决定
// 返回值有这么几种情况:
// 1. 非Promise对象
async function fn1(){
return '字符串'
}
const result1 = fn1()
console.log(result1) // Promise对象状态:resolved,值:'字符串'
// 2. 抛出错误
async function fn2(){
throw '出错了'
}
const result2 = fn2()
console.log(result2) // Promise对象状态:rejected,值:'出错了'
// 3. Promise对象
async function fn3(){
return new Promise((resolve, reject)=>{
// resolve('成功')
// reject('失败')
})
}
const result3 = fn3()
console.log(result3)
// Promise对象状态:和async函数fn3内Promise对象的执行结果一致
// 执行了哪个(resolve或reject),状态就是哪个
// Promise对象值:执行resolve或reject方法时所传入的参数
* await表达式
await 必须写在 async 函数中
await 右侧的表达式一般为 promise 对象
await 返回的是 promise 成功的值
await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
代码例:
// 创建Promise对象
const p = new Promise((resolve, reject)=>{
resolve('用户数据')
// reject('失败了')
})
// await 放在async函数中
async function fn() {
try{
// Promise对象成功,执行此处
let result = await p
console.log(result) // '用户数据'
} catch(e) {
// Promise对象失败,执行此处
console.log(e)
}
}
// 调用函数
fn()
- 对象方法扩展
代码例:
// 声明对象
const obj = {
name: 'sky',
arr1: ['a', 'b', 'c', 'd'],
arr2: [1, 2, 3, 4]
}
// Object.keys 获取对象所有的键名
console.log(Object.keys(obj)) // ['name', 'arr1', 'arr2']
// Object.values 获取对象所有的键值
console.log(Object.values(obj)) // ['sky', ['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
// Object.entries() 返回一个给定对象自身可遍历属性 [key,value] 的数组(二维数组)
console.log(Object.entries(obj)) // [['name', 'sky'], ['arr1', ['a', 'b', 'c', 'd']], ['arr2', [1, 2, 3, 4]]]
// 创建 Map
const m = new Map(Object.entries(obj))
console.log(m.get('name')) // 'sky'
// Object.getOwnPropertyDescriptors 返回指定对象所有自身属性的描述对象
console.log(Object.getOwnPropertyDescriptors(obj))
// 每个对象的属性都有一个描述对象,例:
const obj2 = Object.create(null, {
name: { // 属性name的描述对象
value: 'sky', // 设置值
// 属性特性
writable: true, // 是否可写
configurable: true, // 是否可删除
enumerable: true // 是否可枚举
}
})
ES9
- rest参数与spread扩展运算符
这两个参数在ES6中已经引入,不过在ES6中只针对于数组
ES9中为对象提供了像数组一样的rest参数和扩展运算符
代码例:
// rest参数
function showMessage({id, title, ...info}){
console.log(id) // 1
console.log(title) // '标题'
console.log(info) // {price: 1000, type: '常规'}
}
showMessage({
id: 1,
title: '标题',
price: 1000,
type: '常规'
})
// spread扩展运算符
const profile1 = {
name: 'sky',
gender: '男'
}
const profile2 = {
age: 18
}
const profile3 = {
height: '180cm'
}
const profile4 = {
weight: '70kg'
}
console.log(...profile1) // name: 'sky', gender: '男'
// 利用扩展运算符创建对象属性
const obj = {...profile1, ...profile2, ...profile3, ...profile4}
console.log(obj)
// {name: 'sky', gender: '男', age: 18, height: '180cm', weight: '70kg'}
- 正则扩展
* 命名捕获分组
代码例:
// 声明一个字符串
let str = '<a href="https://www.baidu.com/">百度</a>'
// 普通正则,提取url和其中的标签文本
const reg = /<a href="(.*)">(.*)<\/a>/; // (.*)的部分就是提取处
// 正则命名分组,
const reg2 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/; // (?<{{name}}>.*) {{name}}处起别名
// 执行
const result = reg.exec(str)
const result2 = reg2.exec(str)
console.log(result[1]) // 'https://www.baidu.com/'
console.log(result[2]) // '百度'
console.log(result2.groups) // {url: 'https://www.baidu.com/', text: '百度'}
* 正则断言
代码例:
// 声明一个字符串
let str = '你好12321321我是文字999000结束了'
// 需求,取出其中的数字999000
// 正向断言
const reg = /\d+(?=结)/;
const result = reg.exec(str)
console.log(result[0]) // '999000'
// 反向断言
const reg2 = /(?<=字)\d+/;
const result2 = reg2.exec(str)
console.log(result2[0]) // '999000'
* dotAll模式
代码例:
// dot . 元字符,除换行符以外的任意单个字符
// 声明一个字符串
let str = `
<ul>
<li>
<div>姓名</div>
<p>sky</p>
</li>
<li>
<div>性别</div>
<p>男</p>
</li>
</ul>`
// 需求,取出其中ul内每个li内div标签和p标签中的内容
// 普通正则,规定其中一个li标签
const reg = /<li>\s+<div>(.*?)<\/div>\s+<p>(.*?)<\/p>/;
// 执行
const result = reg.exec(str)
console.log(result[1]) // '姓名'
console.log(result[2]) // 'sky'
// dotAll模式,末尾加s,「.」可以匹配任意字符,全局匹配再加g
const reg2 = /<li>.*?<div>(.*?)<\/div>.*?<p>(.*?)<\/p>/gs;
let result2
let data = []
while(result2 = reg2.exec(str)){
console.log(result2) // 依次打印输出2组数据
data.push({type: result[1], value: result[2]})
}
console.log(data) // [{type: '姓名', value: 'sky'}, {type: '性别', value: '男'}]
ES10
- Object.fromEntries(二维数组或Map转为对象)
可以将一个二维数组或Map转为对象
代码例:
// 转换二维数组
const result = Object.fromEntries([
['name', 'sky'],
['age', 18]
])
console.log(result) // {name: 'sky', age: 18}
// 转换Map
const m = new Map()
m.set('name', 'sky')
const result2 = Object.fromEntries(m)
console.log(result2) // {name: 'sky'}
- trimStart和trimEnd(去除字符串前面或后面的空格)
代码例:
// 声明一个字符串
let str = ' 字符串 '
console.log(str) // ' 字符串 '
// ES5中字符串的方法trim
console.log(str.trim()) // '字符串'
// trimStart
console.log(str.trimStart()) // '字符串 '
// trimEnd
console.log(str.trimEnd()) // ' 字符串'
- flat(多维数组转为低维数组)
代码例:
// flat 将多维数组转化为低维数组
const arr = [1, 2, 3, 4, [5, 6]]
const arr2 = [1, 2, 3, 4, [5, 6, [7, 8, 9]]]
console.log(arr.flat()) // [1, 2, 3, 4, 5, 6]
// 可传入参数,参数为深度,默认值为1
console.log(arr2.flat(1)) // [1, 2, 3, 4, 5, 6, [7, 8, 9]]
console.log(arr2.flat(2)) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
- flatMap(map函数功能 + 转换低维数组)
代码例:
// flatMap,拥有map函数的功能,但可以将返回结果转化为低维数组(深度只有1)
const arr = [1, 2, 3, 4]
const result = arr.map(item => [item * 10])
const result2 = arr.flatMap(item => [item * 10])
console.log(result) // [[10], [20], [30], [40]]
console.log(result2) // [10, 20, 30, 40]
- Symbol.prototype.description(获取Symbol的描述对象)
代码例:
// 创建Symbol,'sky'为此Symbol的描述对象
let s = Symbol('sky')
// 使用description获取描述对象
console.log(s.description) // 'sky'
ES11
- 类的私有属性
代码例:
// 创建类Person
class Person{
// 公有属性
name
// 私有属性
#age
#weight
// 构造方法
constructor(name, age, weight){
this.name = name
this.#age = age
this.#weight = weight
}
// Person内的函数fn
fn() {
console.log(this.name)
console.log(this.#age)
console.log(this.#weight)
}
}
const girl = new Person('小红', 18, '40kg')
console.log(girl) // {name: '小红', #age: 18, #weight: '40kg'}
console.log(girl.name) // '小红'
console.log(girl.#age) // 报错,不能通过类外部的方法获取这个属性
girl.fn() // 执行类Person内部的fn函数,可以正常输出
// '小红'
// 18
// '40kg'
- Promise.allSettled(返回其中所有promise对象的执行结果)
执行allSettled方法需要传入一个数组作为参数,数组内每个元素需要为Promise对象
`
allSettled方法执行后返回一个Promise对象,结果有两个值:
- 返回状态,此状态不受数组中promise对象的状态影响
- 返回值,一个包含方法中所有promise对象执行结果及返回值的数组
代码例:
// 声明两个Promise对象
const p1 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('数据1')
},1000)
})
const p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
reject('失败了')
},1000)
})
// 调用 allSettled 方法
const result = Promise.allSettled([p1, p2])
console.log(result)
// [[PromiseState]]: 'fulfilled'
// [[PromiseResult]]: [{status: 'fulfilled', value: '数据1'}, {status: 'rejected', value: '失败了'}]
- String.prototype.matchAll(正则批量匹配)
代码例:
// 声明一个字符串
let str = `
<ul>
<li>
<div>姓名</div>
<p>sky</p>
</li>
<li>
<div>性别</div>
<p>男</p>
</li>
</ul>`
// 声明正则
const reg = /<li>.*?<div>(.*?)<\/div>.*?<p>(.*?)<\/p>/gs
// 调用方法
const result = str.matchAll(reg)
// result是个可迭代对象,其中有next方法,因此此处可以使用for...of循环
let data = []
for(let item of result){
console.log(item)
data.push({type: item[1], value: item[2]})
}
console.log(data)
// [{type: '姓名', value: 'sky'}, {type: '性别', value: '男'}]
// 使用扩展运算符展开result
const arr = [...result]
console.log(arr)
// [
// ["<li><div>姓名</div><p>sky</p>", "姓名", "sky"],
// ["<li><div>性别</div><p>男</p>", "性别", "男"]
// ]
- 可选链操作符 ?.
代码例:
// ?.
function fn(goods){
// 普通做法,设置商品标题,一层一层判断是否传入
const goodsTitle = goods && goods.mainInfo && goods.mainInfo.title
console.log(goodsTitle) // 只要有一层没传入,则报错
// ?. 可选链操作符
const goodsTitle2 = goods?.mainInfo?.title
console.log(goodsTitle2) // 如果最后的title未传入,则为undefined,不会报错
}
fn({
info: {
title: '标题',
type: '类型'
}
})
- 动态import加载
需求:点击按钮,alert内容’hello’
代码例:
<!-- index.html -->
<button id="btn">按钮</button>
<script src="./js/app.js" type="module"></script>
// app.js
// 传统导入方式,无论用不用,都先导入
// import * as j1 from "./hello.js"
const btn = document.getElementById('btn')
btn.onClick = function(){
// 传统导入方式的使用方式
// j1.hello()
// 动态import加载,import函数
// 该函数执行结果是一个promise对象
import('./hello.js').then(res=>{
console.log(res) // res里面包含所有hello.js内暴露的对象
res.hello()
})
}
// hello.js
export function hello(){
alert('hello')
}
- 新的数据类型-BigInt 大整数(用于更大的数值运算)
// 大整形
let n = 111n
console.log(n, typeof n) // 521n, 'bigint'
// 函数
let m = 123
console.log(BigInt(m)) // 123n
console.log(BigInt(1.1)) // 报错,BigInt不能用于浮点数
// 大数值运算
let max = Number.MAX_SAFE_INTEGER // js内最大安全整数
console.log(max) // 9007199254740991
console.log(max + 1) // 9007199254740992
console.log(max + 2) // 9007199254740992
// 可以看出,正常运算方式已经无法再往上计算
// 这边可以使用BigInt来进行计算
console.log(BigInt(max)) // 9007199254740991n
console.log(BigInt(max) + BigInt(1)) // 9007199254740992n
console.log(BigInt(max) + BigInt(2)) // 9007199254740993n
- globalThis(全局对象)
无论在什么环境下,始终指向全局对象的一个变量
- 浏览器环境下,指向window对象
- node环境(node.js-12)下,指向global对象
- Recorded by Scorpio_sky@2021-01-23