3 ECMAScript7 新特性
3.1 Array.prototype.includes
includes方法用来检测数组中是否包含某个元素,返回布尔类型值
3.2 指数操作符
在ES7中引入指数运算符「**」,用来实现幂运算,功能与Math.pow结果相同
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ES7新特性</title>
</head>
<body>
<script>
// include
const mingzhu = ['西游记', '红楼梦', '三国演义', '水浒传'];
// 判断
console.log(mingzhu.includes('西游记'));
console.log(mingzhu.includes('哈哈哈'));
// **
console.log(2 ** 10);
console.log(Math.pow(2, 10));
</script>
</body>
</html>
4 ECMASript8新特性
4.1 async和await
async和await两种语法结合可以让异步代码像同步代码一样
4.1.1 async函数
- async函数的返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>async函数</title>
</head>
<body>
<script>
// async函数
async function fn() {
// 返回一个字符串
// return 'yaya';
// 返回的结果不是一个Promise类型的对象, 返回的结果就是成功的Promise对象
// 抛出错误 返回的结果是一个失败的Promise
// return;
// throw new Error('出错啦!');
// 返回的结果如果是一个Promise对象
return new Promise((resolve, reject) => {
resolve('成功的数据');
// reject('失败的错误');
});
}
const result = fn();
// console.log(result);
// 调用then方法
result.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
});
</script>
</body>
</html>
4.1.2 await表达式
- await必须写在async函数中
- await右侧的表达式一般为promise对象
- await返回的是promise成功的值
- await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>await</title>
</head>
<body>
<script>
// 创建promise对象
const p = new Promise((resolve, reject) => {
// resolve("成功的值");
reject("失败啦");
});
// await要放在asyc函数中
async function main() {
try {
let result = await p;
console.log(result);
} catch (e) {
console.log(e);
}
}
// 调用函数
main();
</script>
</body>
</html>
async和await结合读取文件
// 1. 引入fs模块
const fs = require("fs");
// 读取 为学
function readWeiXue() {
return new Promise((resolve, reject) => {
fs.readFile('./resources/为学.md', (err, data) => {
// 如果失败
if (err) reject(err);
// 如果成功
resolve(data);
})
})
}
// 读取 插秧诗
function readChaYangShi() {
return new Promise((resolve, reject) => {
fs.readFile('./resources/插秧诗.md', (err, data) => {
// 如果失败
if (err) reject(err);
// 如果成功
resolve(data);
})
})
}
// 读取 观书有感
function readGuanShu() {
return new Promise((resolve, reject) => {
fs.readFile('./resources/观书有感.md', (err, data) => {
// 如果失败
if (err) reject(err);
// 如果成功
resolve(data);
})
})
}
// 声明一个async 函数
async function main() {
// 获取为学内容
let weixue = await readWeiXue();
// 获取插秧内容
let chayang = await readChaYangShi();
// 获取观书有感内容
let guanshu = await readGuanShu();
console.log(weixue.toString());
console.log(chayang.toString());
console.log(guanshu.toString());
}
main();
在终端输入命令
node .\04-async和await结合读取文件.js
async与await封装AJAX请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发送AJAX请求</title>
</head>
<body>
<script>
// 发送AJAX请求,返回的结果是Promise对象
function sendAJAX(url) {
return new Promise((resolve, reject) => {
// 1. 创建对象
const x = new XMLHttpRequest();
// 2. 初始化
x.open('GET', url);
// 3. 发送
x.send();
// 4. 事件绑定
x.onreadystatechange = function() {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
// 成功啦
resolve(x.response);
} else {
// 如果失败
reject(x.status);
}
}
}
})
}
// 测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value => {}, reason => {
// console.log(value);
// }, reason => {})
// async 与await测试
async function main() {
// 发送AJAX请求
let result = await sendAJAX("https://api.apiopen.top/getJoke");
// 再次测试
let tianqi = await sendAJAX('https://www.tianqi.com/');
console.log(tianqi);
}
main();
</script>
</body>
</html>
4.2 对象方法扩展
4.2.1 Object.values和Object.entries
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组
- Object.entries()方法返回一个给定对象自身可遍历属性[key,value] 的数组
4.2.2 Object.getOwnPropertyDescriptors
该方法返回指定对象所有自身属性的描述对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ES8对象方法扩展</title>
</head>
<body>
<script>
// 声明对象
const school = {
name: "yaya",
cities: ['北京', '上海', '深圳'],
xueke: ['前端', 'Java', '大数据', '运维']
};
// 获取对象所有的键
console.log(Object.keys(school));
// 获取对象所有的值
console.log(Object.values(school));
// entries
// console.log(Object.entries(school));
// 创建Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));
// 对象属性的描述对象
// console.log(Object.getOwnPropertyDescriptors(school));
const obj = Object.create(null, {
name: {
// 设置值
value: 'yaya',
// 属性特性
writable: true,
configurable: true,
enumerable: true
}
})
</script>
</body>
</html>
5 ECMAScript9 新特性
5.1 Rest/Spread属性
Rest参数与spread扩展运算符在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>对象展开</title>
</head>
<body>
<!-- Rest 参数与spread 扩展运算符在ES6中已经引入,不过ES6中只针对于数组
在ES9为对象提供了像数组一样的rest参数和扩展运算符
-->
<script>
function connect({host, port, ...user}) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
const skillOne = {
q: '天音波',
}
const skillTwo = {
w: '金钟罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龙摆尾'
}
const mangseng = {...skilOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng);
// ...skillOne => q:'天音波', w: '金钟罩'
</script>
</body>
</html>
5.2 正则表达式命名捕获组
ES9允许命名捕获组使用符号「?」,这样获取捕获结果可读性更强
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正则扩展-命名捕获分组</title>
</head>
<body>
<script>
// // 声明一个字符串
// let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// // 提取url与标签文本
// const reg = /<a href="(.*)">(.*)<\/a>/;
// // 执行
// const result = reg.exec(str);
// console.log(result[1]);
// 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.url); // http://www.atguigu.com
console.log(result.groups.text); // 尚硅谷
</script>
</body>
</html>
5.3 正则表达式反向断言
ES9支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正则扩展-反向断言</title>
</head>
<body>
<script>
// 声明字符串
let str = 'JS35223你知道吗3452哈哈哈哈';
// 正向断言
// const reg = /\d+(?=哈)/;
// const result = reg.exec(str);
// console.log(result);
// 反向断言
const reg = /(?<=吗)\d+/;
const result = reg.exec(str);
console.log(result);
</script>
</body>
</html>
5.4 正则表达式dotAll模式
正则表达式中点.匹配除回车外的任何单字符,标记「s」改变这种行为,允许行
终止符出现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>正则扩展-dotAll模式</title>
</head>
<body>
<script>
// dot . 元字符 除换行符以外的任意单个字符
let str = `
<ul>
<li>
<a>肖生客的救赎</a>
<p>上映日期:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-07-06</p>
</li>
</ul>`;
// 声明正则
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
// 执行匹配
// const result = reg.exec(str);
let result;
let data = [];
while (result = reg.exec(str)) {
data.push({title: result[1], time: result[2]});
}
// 输出结果
console.log(data);
</script>
</body>
</html>
6 ECMAScript10新特性
6.1 Object.fromEntries
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Object.fromEntries</title>
</head>
<body>
<script>
// 二维数组
// const result = Object.fromEntries([
// ['name', 'yaya'],
// ['xueke', 'Java, 大数据, 前端, 云计算']
// ]);
// Map
// const m = new Map();
// m.set('name', 'yaya');
// const result = Object.fromEntries(m);
// Object.entries ES8
const arr = Object.entries({
name: "yaya"
})
console.log(arr);
</script>
</body>
</html>
6.2 trimStart和trimEnd
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>trimStart与trimEnd</title>
</head>
<body>
<script>
// trim
let str = ' iloveyou';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
</script>
</body>
</html>
6.3 Array.prototype.flat与flatMap
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flat与flatMap</title>
</head>
<body>
<script>
// flat 平
// 将多维数组转化为低位数组
// const arr = [1, 2, 3, 4, [5, 6]];
// const arr = [1, 2, 3, 4, [5, 6, [7, 8, 9]]];
// 参数为深度 是一个数字
// console.log(arr.flat(2));
// flatMap
const arr = [1, 2, 3, 4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);
</script>
</body>
</html>
6.4 Symbol.prototype.description
获取Symbol的字符串描述
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symbol.prototype.description</title>
</head>
<body>
<script>
// 创建Symbol
let s = Symbol('yaya');
console.log(s.description); // yaya
</script>
</body>
</html>
7 ECMAScript 11新特性
7.1 String.prototype.matchAll
适合批量处理
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let str = `
<ul>
<li>
<a>肖生客的救赎</a>
<p>上映日期:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-07-06</p>
</li>
</ul>`;
// 声明正则
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg;
// 调用方法
const result = str.matchAll(reg);
// for (let v of result) {
// console.log(v);
// }
const arr = [...result];
</script>
</body>
</html>
7.2 类的私有属性
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>私有属性</title>
</head>
<body>
<script>
class Person {
// 共有属性
name;
// 私有属性
#age;
#weight;
// 构造方法
constructor(name, age, weight) {
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro() {
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
// 实例化
const girl = new Person('小红', 18, '45kg');
// console.log(girl.name);
// console.log(girl.#age);
// console.log(girl.#weight);
girl.intro();
</script>
</body>
</html>
7.3 Promise.allSettled
- Promise.all将在Promises数组中的其中一个Promises失败后立即失败。
- Promise.allSettled将永远不会失败,一旦数组中的所有Promises 被完成或失败,它就会完成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise.allSettled</title>
</head>
<body>
<script>
// 声明两个promise对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('商品数量 - 1');
}, 1000)
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('商品数量 - 2');
reject('出错啦');
}, 1000)
});
// 调用allsettled方法
// const result = Promise.allSettled([p1 ,p2]);
const result = Promise.all([p1, p2]);
console.log(result);
</script>
</body>
</html>
7.4 可选链操作符
?. 判断前面的值有没有传入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>可选链操作符</title>
</head>
<body>
<script>
// ?. 判断前面的值有没有传入
function main(config) {
// const dbHost = config && config.db && config.db.host;
const dbHost = config?.db?.host;
console.log(dbHost);
}
main({
db: {
host: "192.168.1.100",
username: "root",
},
cache: {
host: "192.168.1.200",
username: "admin",
},
});
</script>
</body>
</html>
7.5 动态import导入
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态 import</title>
</head>
<body>
<button id="btn">点击</button>
<script src="./js/app.js" type="module"></script>
</body>
</html>
app.js
// import * as m1 from "./hello.js";
// 获取元素
const btn = document.getElementById('btn');
btn.onclick = function () {
import('./hello.js').then(module => {
module.hello();
});
}
hello.js
export function hello() {
alert('Hello');
}
7.6 BigInt类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BigInt</title>
</head>
<body>
<script>
// 大整型
// let n = 521n;
// console.log(n, typeof(n));
// 函数
// let n = 123;
// console.log(BigInt(n));
// console.log(BigInt(1.2));
// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);
console.log(max + 1);
console.log(max + 2);
console.log(BigInt(max));
console.log(BigInt(max) + BigInt(1));
console.log(BigInt(max) + BigInt(2));
</script>
</body>
</html>
7.7 globalThis对象
全局属性 globalThis 包含全局的 this 值,类似于全局对象(global object)
写代码时如果想要对全局变量进行操作,这时候可以忽略环境直接使用globalThis
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>globalThis</title>
</head>
<body>
<script>
console.log(globalThis);
</script>
</body>
</html>
js文件:
console.log(globalThis);