JavaScript进阶(五)
ECMAScript 6-11
三、ECMASript 7 新特性
3.1.Array.prototype.includes
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
3.2.指数操作符
在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ES7 新特性</title>
</head>
<body>
<script>
// includes indexOf 也可以判断,不过它判断的是如果存在返回一个-1
const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
//判断
console.log(mingzhu.includes('西游记'));//true
console.log(mingzhu.includes('金瓶梅'));//false
/* indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
语法 stringObject.indexOf(searchvalue,fromindex)
searchvalue 必需。规定需检索的字符串值。
fromindex 可选的整数参数。规定在字符串中开始检索的位置。
它的合法取值是 0 到 stringObject.length - 1。
如省略该参数,则将从字符串的首字符开始检索。
说明:
该方法将从头到尾地检索字符串 stringObject,看它是否
含有子串 searchvalue。开始检索的位置在字符串的 fromindex 处
或字符串的开头(没有指定 fromindex 时)。
如果找到一个 searchvalue,则返回 searchvalue 的第一次出现的位置。
stringObject 中的字符位置是从 0 开始的。
注释:indexOf() 方法对大小写敏感!如果要检索的字符串值没有出现,则该方法返回 -1。
代码演示:
<script type="text/javascript">
var str="Hello world!"
document.write(str.indexOf("Hello") + "<br />") //0
document.write(str.indexOf("World") + "<br />") //-1
document.write(str.indexOf("world")) //6
</scritp>
*/
// ** 幂运算
console.log(2 ** 10);// 输出为1024,跟Math.pow(2,10)效果是一样的
console.log(Math.pow(2, 10));//1024
</script>
</body>
</html>
四、ECMASript 8 新特性
4.1.async 和 await
async 和 await 两种语法结合可以让异步代码像同步代码一样
4.1.1.async 函数
1.async 函数的返回值为 promise 对象
2. promise 对象的结果由 async 函数执行的返回值决定
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>async函数</title>
</head>
<body>
<script>
//在普通函数前加上 async 就变为 async函数
async function fn(){
// 返回的结果不是一个 Promise 类型的对象, 则这个函数返回的结果就是成功 Promise 对象
// 返回一个字符串
return '尚硅谷';
}
const result = fn();
console.log(result);
//在普通函数前加上 async 就变为 async函数
async function fn2(){
// 返回的结果不是一个 Promise 类型的对象, 则这个函数返回的结果就是成功 Promise 对象
return; //直接写return,返回的值是undefined
}
const result2 = fn2();
console.log(result2);
//在普通函数前加上 async 就变为 async函数
async function fn3(){
//抛出错误, 返回的结果是一个失败的 Promise
throw new Error('出错啦!');
}
const result3 = fn3();
console.log(result3);
//在普通函数前加上 async 就变为 async函数
async function fn4(){
//返回的结果如果是一个 Promise 对象
return new Promise((resolve, reject)=>{
resolve('成功的数据');
// reject("失败的错误");
});
}
const result4 = fn4();
//调用 then 方法
result4.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
</script>
</body>
</html>
4.1.2.await 表达式
1.await 必须写在 async 函数中
2. await 右侧的表达式一般为 promise 对象
3. await 返回的是 promise 成功的值
4. await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>await</title>
</head>
<body>
<script>
//创建 promise 对象,promise对象有两个属性,
//一个表示他的状态,一个属性表示他状态所对应的值
const p = new Promise((resolve, reject) => {
//通过调研resolve函数把promise对象的状态修改为成功,
//并把它的值通过传参修改它成功的值为用户数据
resolve("用户数据");
})
// await 要放在 async 函数中.但是async函数里可以没有await
async function main() {
let result = await p;//await返回结果是promise对象成功的值
console.log(result);
}
//调用函数
main();//用户数据
//创建 promise 对象
const p2 = new Promise((resolve, reject) => {
reject("失败啦!");
})
// await 要放在 async 函数中.但是async函数里可以没有await
async function main2() {
// 如果是失败,要有try...catch进行捕获,在catch里得到失败的结果,
try {
let result = await p2;//
console.log(result);
} catch (e) {
console.log(e);
}
}
//调用函数
main2();//失败啦!
</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) => {
//如果失败
//把这个函数(readChaYangShi)返回的promise对象的状态变为失败
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);
})
})
}
// 上面每个函数返回结果都是一个promise对象
//声明一个 async 函数
async function main(){
//获取为学内容
let weixue = await readWeiXue();//await返回的为promise对象成功的值
//获取插秧诗内容
let chayang = await readChaYangShi();
// 获取观书有感
let guanshu = await readGuanShu();
console.log(weixue.toString());
console.log(chayang.toString());
console.log(guanshu.toString());
}
main();//然后直接 node +js文件名 运行
async和await结合发送ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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);
}
}
}
})
}
//promise then 方法测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{
// console.log(value);
// }, reason=>{})
// async 与 await 测试 axios
async function main(){
//发送 AJAX 请求
let result = await sendAJAX("https://api.apiopen.top/getJoke");//笑话接口
//天气接口
let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')
console.log(result);
console.log(tianqi);
}
main();
</script>
</body>
</html>
对象方法扩展:
4.2.Object.values 和 Object.entries
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组
- Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
4.3.Object.getOwnPropertyDescriptors
该方法返回指定对象所有自身属性的描述对象
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ES8 对象方法扩展</title>
</head>
<body>
<script>
//声明对象
const school = {
name:"尚硅谷",
cities:['北京','上海','深圳'],
xueke: ['前端','Java','大数据','运维']
};
//获取对象所有的键
console.log(Object.keys(school));
//获取对象所有的值
console.log(Object.values(school));
//entries
//返回的结果是一个数组,且每个元素也是一个数组(数组里面第一个是键,第二个是值),
//这样方便创建一个map
console.log(Object.entries(school));
//创建 Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));
//对象属性的描述对象,返回结果为下面name中的内容,我们可以通
//过他对对象进行更深层次的克隆,比如这个对象是否可以删除、枚举。。。
console.log(Object.getOwnPropertyDescriptors(school));
/*
// 我们创建一个对象
//第一个参数为原型对象,此处我们设置为null,第二个参数为描述对象
const obj = Object.create(null, {
// name的值是一个对象,也必须是一个对象
name: {
//设置值
value: '尚硅谷',
//属性特性
writable: true,//是否可写
configurable: true,//是否可以删除
enumerable: true//是否可以枚举
}
});
*/
</script>
</body>
</html>
五、ECMASript 9 新特性
5.1.Rest/Spread 属性
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组, 在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
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'
});
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>对象展开</title>
</head>
<body>
<!--
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
-->
<script>
//rest 参数
//用user保存剩下的参数,就不用我们一个一个的去解构赋值了
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: '天音波'
// w: '金钟罩'
}
//用扩展运算符展开为 ...skillOne => q: '天音波', w: '金钟罩'
const skillTwo = {
w: '金钟罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龙摆尾'
}
const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng)
</script>
</body>
</html>
5.2.正则表达式扩展:命名捕获组
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
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);
console.log(result.groups.text);
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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 与 『标签文本』
//第一个小括号的值为 http://www.atguigu.com ,第二个小括号的值为 尚硅谷
const reg = /<a href="(.*)">(.*)<\/a>/;
//执行
const result = reg.exec(str);
console.log(result);
console.log(result[1]);
console.log(result[2]);
/*
exec() 方法用于检索字符串中的正则表达式的匹配。语法:RegExpObject.exec(string)
返回值:返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
说明:exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test()
方法以及支持正则表达式的 String 对象的方法更为复杂。如果 exec() 找到了匹配的
文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相
匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),
第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。
除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配
文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,
在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match()
返回的数组是相同的。但是,当 RegExpObject 是一个全局正则表达式时,exec()
的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处
开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,
它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。
这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。
当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
重要事项:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,
就必须手动地把 lastIndex 属性重置为 0。
提示:请注意,无论 RegExpObject 是否是全局模式,exec() 都会把完整的细
节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,
后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用
exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。
*/
// 命名捕获分组的处理
let str2 = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
//对结果添加一个属性方便我们去提取
const reg2 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result2 = reg2.exec(str2);
console.log(result2);
console.log(result2.groups.url);
console.log(result2.groups.text);
</script>
</body>
</html>
5.3.正则表达式扩展:反向断言
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
//声明字符串
let str = 'JS5211314 你知道么 555 啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正则扩展-反向断言</title>
</head>
<body>
<script>
//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
//(?=)根据当前匹配后面的内容去判断前面的内容是否是满足条件的
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result);
/* /^(-?\d+)(\.\d+)?$/
这个正则就是匹配数字
-?表示前面可以有一个可选的减号
\d+表示一到多个数字,(-?\d+)这个表示整数部分
(\.\d+)?表示一个小数点跟多个数字,?表示前面这部分是可选的,
这部分匹配一个可选的小数部分
*/
//反向断言
//(?<=)根据当前匹配前面的内容去判断后面的内容是否是满足条件的
const reg2 = /(?<=么)\d+/;
const result2 = reg2.exec(str);
console.log(result2);
//总结:根据目标内容前面和后面的内容对他做唯一性的识别
</script>
</body>
</html>
5.4.正则表达式扩展: dotAll 模式
正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行 终止符出现
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>/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);
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正则扩展-dotAll模式</title>
</head>
<body>
<script>
//dot 即 . ,元字符,表示除换行符以外的任意单个字符
// dotAll 让.匹配任意字符
// 需求:将电影名称和对应的上映时间提取出来存到一个对象里面
let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
// 不用dotAll模式
//声明正则
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/; // \s 表示换行,过于麻烦
// 使用dotAll模式
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//执行匹配
const result = reg.exec(str);
const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;//gs表示全局匹配
let result2;
let data = [];
while(result2 = reg2.exec(str)){
console.log(result2);
data.push({title: result2[1], time: result2[2]});
}
//输出结果
console.log(data);
</script>
</body>
</html>
六、ECMASript 10 新特性
6.1.Object.fromEntries
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Object.fromEntries</title>
</head>
<body>
<script>
//Object.fromEntries用来创建一个对象,不过他所接收的参数为 二位数组 或者是 Map
//二维数组
const result = Object.fromEntries([
['name','尚硅谷'],
['xueke', 'Java,大数据,前端,云计算']
]);
console.log(result);
//Map
const m = new Map();
m.set('name','ATGUIGU');
const result2 = Object.fromEntries(m);//将二位数组转换为对象
console.log(result2);
//Object.entries ES8中的一个方法,他可以将一个对象转换为一个二位数组
const arr = Object.entries({
name: "尚硅谷"
})
console.log(arr);
</script>
</body>
</html>
6.2.trimStart 和 trimEnd
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>trimStart 与 trimEnd</title>
</head>
<body>
<script>
// trimStart 与 trimEnd 字符串的两个扩展方法,
//trimStart负责清除字符串左侧的空白,trimEnd负责清除字符串右边的空白
// trim 在es5中就存在的,用来清除字符串两边的空白字符
let str = ' iloveyou ';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
</script>
</body>
</html>
6.3.Array.prototype.flat 与 flatMap
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flat 与 flatMap</title>
</head>
<body>
<script>
// flat 与 flatMap 数组的两个方法
//flat 将一个数组的维数降低
//将多维数组转化为低位数组
const arr = [1,2,3,4,[5,6]];
console.log(arr.flat());
const arr2 = [1,2,3,4,[5,6,[7,8,9]]];
console.log(arr2.flat())//此处只把三维数组变为二位数组
//参数为深度 是一个数字
console.log(arr2.flat(2)); //将三维数组变为一维数组,默认值为1
//flatMap
const arr3 = [1,2,3,4];
const result = arr3.map(item => item * 10);//将每一项乘以10
console.log(result);
const result2 = arr3.map(item => [item * 10]);//将每一项乘以10
console.log(result2);//二位数组
//flatMap将多维数组转换为一维数组
const result3 = arr3.flatMap(item => [item * 10]);
console.log(result3);
</script>
</body>
</html>
6.4.Symbol.prototype.description
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symbol.prototype.description</title>
</head>
<body>
<script>
// Symbol.prototype.description用来获取Symbol的字符串描述
//创建 Symbol
let s = Symbol('尚硅谷');
console.log(s.description);//尚硅谷
</script>
</body>
</html>
第 7 章 ECMASript 11 新特性
7.1.String.prototype.matchAll
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>String.prototype.matchAll</title>
</head>
<body>
<script>
// String.prototype.matchAll 用来得到正则批量匹配的结果
let str = `<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//声明正则
//s表示模式修正符,就是dotAll模式,让 . 匹配所有的单个字符。
//因为是批量匹配,所以模式修正符的g也不能省略
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
//调用方法
//返回的结果是一个可迭代对象,有next方法,所以我们可以使用for...of进行遍历
const result = str.matchAll(reg);
console.log(result);
// 使用for...of进行遍历
// for(let v of result){
// console.log(v);
// }
// 使用扩展运算符进行展开
const arr = [...result];
console.log(arr);
</script>
</body>
</html>
7.2.类的私有属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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);
//报错,私有属性在类的外面直接操作是不被允许的,我们要在类里面进行操作
// console.log(girl.#age);
// console.log(girl.#weight);
girl.intro();
</script>
</body>
</html>
7.3.Promise.allSettled
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise.allSettled</title>
</head>
<body>
<script>
// Promise.allSettled 接收一个promise数组,返回的是一个promise对象,
//返回的结果永远是成功的状态
//声明两个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]);
console.log(result);
// all方法也是接收一个promise对象,但是他返回的结果是要根据每一个promise的状态决定的,
// 只有他们都成功时,他才会成功,如果有一个失败,他就会失败
const res = Promise.all([p1, p2]);
console.log(res);
// 他们都用来做批量任务的场景
</script>
</body>
</html>
7.4.可选链操作符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可选链操作符</title>
</head>
<body>
<script>
//可选链操作符,它的符号是 ?. 的组合
function main(config){
//先判断是否存在 config,然后 config.db ,最后 config.db.host
// const dbHost = config && config.db && config.db.host;
//表示前面这个值是否传入,在判断后面的属性,这样即使我
//们把下方的这个给删除它也不会报错,输出为undefined
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'
}
})
</script>
</body>
</html>
7.5.动态 import 导入
hello.js
export function hello(){
alert('Hello');
}
app.js
// 静态引入
// import * as m1 from "./hello.js";
//获取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
// 动态引入,即用的时候在导入
//import函数的返回结果是一个promise对象,而这个promise成功的值就是这个模块里暴露出来的对象
import('./hello.js').then(module => {
console.log(module);
module.hello();//弹出 Hello
});
}
7.6.globalThis 对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>globalThis</title>
</head>
<body>
<script>
// globalThis 始终是指向全局对象的,无论执行环境是什么
console.log(globalThis);//window
</script>
</body>
</html>
console.log(globalThis);
//在node.js中全局对象是global
7.7.BigInt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BigInt</title>
</head>
<body>
<script>
//大整形,主要用来更大数值的运算
let n = 521n;//在末尾加 n 即可
console.log(n, typeof(n));
//BigInt把整数转换为一个大整形的值
let n2 = 123;
console.log(BigInt(n2));
// 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))
//但是要注意不能与普通的整数做运算,要把这个整数也变为BigInt
console.log(BigInt(max) + BigInt(1))
console.log(BigInt(max) + BigInt(2))
</script>
</body>
</html>