ES7-11新特新速览
ES7新特性
数组新特性
includes()
幂运算
2的10次方
console.log(2 ** 10);//1024
ES8新特性
async和await
async和await两种语法结合可以让异步代码像同步代码一样
异步编程的解决方案:
- 生成器函数
- promise
- async和await
async函数
- async函数的返回值为promise对象
- promise对象的结果是由async函数执行的返回值决定的
promise类型 的对象
return throw new Error("出错了");
return new Promise(()=>{
resolve('成功');
})
async函数的声明
async function fn (){
return 'yxj'
}
const result = fn();
console.log(result);//Promise { <state>: "fulfilled", <value>: "yxj" }
async函数的返回类型(是一个promise对象)
-
只要返回值的类型不是一个promise类型的对象则async函数的返回结果就是一个成功的promise对象
async function fn (){ //只要返回的不是promise类型的对象,则返回结果就是成功的promise对象 return; } const result = fn(); console.log(result);//Promise { <state>: "fulfilled", <value>: undefined }
-
抛出promise类型错误
async function fn (){ throw new Error("出错了"); } const result = fn(); console.log(result);//Promise { <state>: "rejected", <reason>: Error }
-
返回的结果是一个promise对象时
promise的返回值会成为他所在函数的返回值
async function fn (){ return new Promise((resolve,reject)=>{ resolve("成功"); }) } const result = fn();//此时fn返回的结果也是成功的 console.log(result);//Promise { <state>: "fulfilled", <value>: "成功" } //fn返回的值就是Promise返回的值
总结:
- 声明async函数时在function前加async
- 他的返回结果是一个promise类型的对象
- 对象的状态由函数内部的return语句决定
可以调用then方法
async function fn (){
return new Promise((resolve,reject)=>{
reject("失败了");
})
}
const result = fn();
result.then((value)=>{
console.log(value);
},(reason)=>{
console.log(reason);
})
await表达式
-
await必须写在async函数中
-
await右侧的表达式一般为promise对象
-
await返回的是promise成功的值
-
await的promise失败了就会抛出异常,需要通过try…catch捕获处理
// 先创建一个promise对象
const p = new Promise((resolve,reject)=>{
// resolve("成功的值");
reject("error");
})
async function fn(){
// let result = await p;
// console.log(result)
try{
let result = await p;
console.log(result)
}catch(e){
console.log(e);//error
}
;
}
// fn();//成功的值
fn();//error
async和await结合读取文件内容
//引入fs模块
const fs = require("fs");
// 读取文件1
function readA() {
return new Promise((resolve,reject)=>{
fs.readFile("./ddy.md",(err,data)=>{
if(err){
reject(err);
}else{
resolve(data);
}
})
})
}
// 读取文件2
function readB() {
return new Promise((resolve,reject)=>{
fs.readFile("./study.md",(err,data)=>{
if(err){
reject(err);
}else{
resolve(data);
}
})
})
}
// 读取文件3
function readC() {
return new Promise((resolve,reject)=>{
fs.readFile("./look.md",(err,data)=>{
if(err){
reject(err);
}else{
resolve(data);
}
})
})
}
// 声明一个async函数
async function main(){
// 获取a
let A = await readA();
// 获取b
let B = await readB();
// 获取c
let C = await readC();
console.log(A.toString());
console.log(B.toString());
console.log(C.toString());
}
main();
/**
* PS F:\前端\ES6~11\async> node .\async.js
天行健,君子以自强不息.
学而时习之不亦说乎?
读书破万卷,下笔如有神.
PS F:\前端\ES6~11\async>
*/
Promise与then方法结合发送Ajax
// 发送Ajax请求,返回结果是Promise对象
function sendAJAX(url){
return new Promise((resolve,reject)=>{
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化
xhr.open('GET',url);
// 发送
xhr.send();
// 事件绑定
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status >= 200&&xhr.status <= 300){
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
})
}
// 测试
const result = sendAJAX('https://api.apiopen.top/getJoke');
console.log(result);//Promise { <state>: "pending" }
sendAJAX('https://api.apiopen.top/getJoke').then((value)=>{
console.log(value);
},(reason)=>{
})
async和await结合发送Ajax
function sendAJAX(url){
return new Promise((resolve,reject)=>{
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化
xhr.open('GET',url);
// 发送
xhr.send();
// 事件绑定
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status >= 200&&xhr.status <= 300){
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
})
}
// async await测试 axios的返回结果就是一个promise对象
async function main(){
// 向Ajax发送请求
let result = await sendAJAX("https://api.apiopen.top/getJoke");
console.log(result);
// 如果还要向别的服务器发送请求
let result2 = await sendAJAX("https://www.tianqiapi.com/api/?version=v1&city=北京%appid=23941491&appsecret=TXoD5e8P");
console.log(result2);
}
main();
对象方法的扩展
const obj = {
name:'yxj',
age:18,
sex:'男'
};
-
Object.keys()
获取对象的键
console.log(Object.keys(obj));//[ "name", "age", "sex" ]
-
Object.values()
获取对象的值
console.log(Object.values(obj));//[ "yxj", 18, "男" ]
-
Object.entries
获取对象的键值
console.log(Object.entries(obj));//0: Array [ "name", "yxj" ] 1: Array [ "age", 18 ] 2: Array [ "sex", "男" ]
-
Object.getOwnPropertyDesciptors
返回对象属性的描述对象,深层次克隆对象时会使用到
console.log(Object.getOwnPropertyDescriptors(obj)); /* age: Object { value: 18, writable: true, enumerable: true, … } configurable: true //是否可以删除 enumerable: true //是否可以枚举 value: 18 //值 writable: true //是否可写 <prototype>: Object { … } name: Object { value: "yxj", writable: true, enumerable: true, … } sex: Object { value: "男", writable: true, enumerable: true, … } <prototype>: Object { … } */
对象属性的补充:
- configurable 是否可以删除
- enumerable 是否可以枚举
- writable: true 是否可写
ES9的新特性
rest参数与扩展运算符在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符
rest参数
function connect({host,port,...user}){
console.log(host);//127.0.0.1
console.log(port);//3306
console.log(user);//Object { username: "root", password: "root" }
}
connect({
host:'127.0.0.1',
port:3306,
username:'root',
password:'root'
})
扩展运算符
const name = {
name:'yxj',
};
const age = {
age:18,
};
const sex = {
sex:'男',
};
// 将四个对象的属性合并为一个一个对象
const person = {...name,...age,...sex}
console.log(person);//Object { name: "yxj", age: 18, sex: "男" }
正则扩展
命名捕获分组
可以对分组匹配的结果进行命名 方便对结果进行处理
let str1 = '<a href="https://www.yxj.com">英达网</a>';
// 提取url与标签文本
const reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg1.exec(str1);
console.log(result);//多了 groups: Object { url: "https://www.yxj.com", text: "英达网" }
反向断言
断言:判断匹配结果是否正确
正向断言
let str = 'JS555211314行内555溜了溜了';//提取555
//根据后边的内容判断前面的内容是否合法
const reg = /\d+(?=溜)/;
const result = reg.exec(str);
console.log(result);//[555]
反向断言
let str = 'JS555211314行内555溜了溜了';//提取555
//根据前边的内容判断后面的内容是否合法
const reg = /(?<=内)\d+/;
const result = reg.exec(str);
console.log(result);//[555]
dotAll模式
dot . 元字符 除换行符以外的任意单个字符
//把ul里的电影名称和对应的上映时间提取出来,存到对象里
let str = `
<ul>
<li>
<a>泰坦尼克号</a>
<p>上映日期:1997-12-19</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-07-06</p>
</li>
</ul>`;
// 以前的做法
const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
const result = reg.exec(str);
console.log(result);
// dot .
const reg1 = /<li>.*?<a>.*?<\/a>.*?<p>.*?<\/p>/gs;
const result1 = reg.exec(str);
console.log(result1);
ES10的新特性
Object.fromEntries
-
可以用来创建一个对象
-
他的参数可以是二维数组或者是Map
-
二维数组的情况(将二维数组转为了对象)
const result = Object.fromEntries([ ['name','yxj'], ['skill','html.css,javascript,vue'] ]) console.log(result);//Object { name: "yxj", skill: "html.css,javascript,vue" }
-
Map的情况
const m = new Map(); m.set('name','yxj'); const result2 = Object.fromEntries(m); console.log(result2);//Object { name: "yxj" }
总结:
es8里的Object.entries方法 与Object.fromEntries其实是一个逆运算 Object.entries将一个对象转换为一个二维数组 Object.fromEntries可以将一个二维数组转为对象
字符串的扩展方法
- trim ES6提出 用于清除两侧的空白
- trimSta ES10提出 用于清除左侧的空白
- trimEnd ES10提出 用于清除右侧的空白
let str = ' yxj ';
console.log(str);
console.log(str.trimSta());
console.log(str.trimEnd());
数组的方法
flat
-
将多维数组转换成低维数组
-
参数默认为1表示深度,相当于展开数组层数
const arr = [[1,2],[3,4],[5]]; console.log(arr.flat());//Array(5) [ 1, 2, 3, 4, 5 ]
flatMap
- 与数组的map方法类似
- 能够把数组降维
Symbol的描述属性
- description
let s = Symbol('yxj');
console.log(s.description);//yxj
ES11的新特性
class私有属性
class person{
//共有属性
name;
//私有属性
#age;
#weight;
constructor(name,age,weight){
this.name = name;
this.#age = age;
this.#weight = weight;
}
}
promise.allSettled
-
可以分别得到每一个promise的状态及结果
-
用于处理批量的异步任务
const p1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("商品数据 -1 "); },1000) }); const p2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("商品数据 -1 "); },1000) }); // 调用allsettled方法 可以分别得到每一个promise的状态及结果 const result = Promise.allSettled([p1,p2]); console.log(result); /* Promise { <state>: "pending" } <state>: "fulfilled" <value>: Array [ {…}, {…} ] 0: Object { status: "fulfilled", value: "商品数据 -1 " } 1: Object { status: "fulfilled", value: "商品数据 -1 " } length: 2 <prototype>: Array [] <prototype>: Promise.prototype { … } */
promise.all
- 每一项promise都成功整体才会返回成功的promise
- 也用于处理批量的异步任务
可选链操作符
- ?.
- 在获取深层次对象类型的参数时用到
//?.
//在获取深层次对象类型的参数时用到
function main (config){
const dbHost = config && config.db && config.db.host;
console.log(dbHost);//192.168.1.100
// 使用?.可以免去层层判断
const dbHost2 = config?.db?.host;
console.log(dbHost2);
}
main({
db:{
host:'192.168.1.100',
username:'root'
},
cache:{
host:'192.168.1.200',
username:'admin'
}
})
动态import
- 动态import可以实现按需加载
- import()函数返回结果是一个Promise对象
- Promise对象成功的值就是暴露出来的./app.js里的对象
const btn = document.getElementById("btn");
btn.onclick = function(){
import('./app.js').then(module=>{
module.methods();
})
}
bigInt
- 大整形
- 只能操作整形
- 表示方式:在普通整形的基础上+n
- 用于大数值的运算
let n =521n;
console.log(n);//521n
console.log(typeof n);//bigint
-
函数形式
let n =521; console.log(BigInt(n));//521n
-
最大安全整数
let max = Number.MAX_SAFE_INTEGER; console.log(max);//9007199254740991 console.log(BigInt(max) + BigInt(5));//9007199254740996n
绝对全局对象
- globalThis
- 始终指向全局对象
console.log(globalThis);//window
let that = globalThis;