ES6
函数参数默认值
function add(a,b,c=10){
return a + b + c;
}
let result = add(1,2);
console.log(result); // 13
rest 参数
ES6引入rest参数,用于获取函数的实参,用来替代arguments
ES5获取实参的方式
function date(){
console.log(arguments);
}
date('白芷','阿娇','思慧')
// Arguments(3) ['白芷', '阿娇', '思慧', callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 0: "白芷"
// 1: "阿娇"
// 2: "思慧"
// callee: ƒ date()
// length: 3
// Symbol(Symbol.iterator): ƒ values()
// [[Prototype]]: Object
rest参数
function date(...args){
console.log(args);
}
date('白芷','阿娇','思慧') //['白芷', '阿娇', '思慧']
function fn(a,b,c,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,63,2)
// 1
// 2
// [4, 5, 63, 2]
ES6中的三个点 … 有两个名字:rest参数和扩展运算符.
- 当用在函数定义时的形参前面时,称为rest参数,当函数调用时,用于接收不确定的参数.
- 当与解构赋值组合使用时,称为rest参数,用于接收剩余的值,存储在数组中.
- 当用在字符串或数组前面时称为扩展运算符,将数组或字符串进行拆解
// 扩展运算符的运用
// 1.数组的合并
const kuaizi = ['王太利','肖央']
const fenghuang = ['曾毅','玲花']
const all = kuaizi.concat(fenghuang) // ['王太利', '肖央', '曾毅', '玲花']
const all1 = [...kuaizi,...fenghuang] // ['王太利', '肖央', '曾毅', '玲花']
// 2.数组的克隆
const sanzhihua = ['e','g','m'];
const sanyecai = [...sanzhihua];//['e','g','m']
// 3.将伪数组转为真正的数组
const divs = document.querySelectorAll('div')
const divArr = [...divs] // [div,div,div]
Symbol运算符
表示独一无二的值,他是JS语言的第7种数据类型。
- 它的值是唯一的,用来解决命名冲突的问题
- 不能与其他数据做运算
- 不能使用for遍历,但是可以使用Reflect.ownKeys来获取对象的所有健名
// 创建Symbol
let s = Symbol() // Symbol()
let s2 = Symbol('嘿嘿')
let s3 = Symbol('嘿嘿')
console.log(s2 === s3) //false
let s4 = Symbol.for('嘿嘿')
let s5 = Symbol.for('嘿嘿')
console.log(s4 === s5) //true
迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
-
Es6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
-
原生具备Iterator接口的数据(可用for of遍历)
Array
Arguments
Set
Map
String
TypedArray
NodeList -
工作原理
a) 创建一个指针对象,指向当前数据结构的起始位置。
b) 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
c) 接下来不断的调用next方法,指针一直往后移动,直到指向最后一个成员
d) 每调用next方法返回一个包含value和done属性的对象 -
注:需要自定义遍历数据的时候,要想到迭代器
// 声明一个数组
const xiyou = [ '唐僧','孙悟空','猪八戒','沙僧' ]
for(let v of xiyou){
console.log(v);
}
let iterator = xiyou[Symbol.iterator]();
// 调用对象的next方法
console.log(iterator.next()) // {value: '唐僧', done: false}
console.log(iterator.next()) // {value: '孙悟空', done: false}
console.log(iterator.next()) // {value: '猪八戒', done: false}
console.log(iterator.next()) // {value: '沙僧', done: false}
console.log(iterator.next()) // {value: undefined, done: true}
// 自定义遍历数据
const banji = {
name:"终极一班",
stus:[
'小王',
'小张',
'小陈'
],
[Symbol.iterator](){
let index = 0
let _this = this
return {
next:function(){
if(index < this.stus.length){
const result = { value:_this.stus[i],done:false}
index++
return result
}else{
return { value:undefined,done:true}
}
}
}
}
生成器
生成器其实就是一个特殊的函数
function * gen(){
console.log('111')
yield '一只没有耳朵'; // 函数代码的分隔符
console.log('222')
yield '一只没有尾部';
console.log('333')
yield '真奇怪';
console.log('444')
}
let iterator = gen();
iterator.next(); // 111
iterator.next(); // 222
iterator.next(); // 333
iterator.next(); // 444
function * gen(){
yield '一只没有耳朵'; // 函数代码的分隔符
yield '一只没有尾部';
yield '真奇怪';
}
let iterator = gen();
console.log(iterator.next()); // {value: '一只没有耳朵', done: false}
console.log(iterator.next()); // {value: '一只没有尾部', done: false}
console.log(iterator.next()); // {value: '真奇怪', done: false}
console.log(iterator.next()); // {value: undefined, done: true}
// 遍历
for(let v of gen()){
console.log(v);
}
// 一只没有耳朵
// 一只没有尾部
// 真奇怪
生成器函数参数
function * gen(arg){
console.log(arg);
let one = yield 111; // 函数代码的分隔符
console.log(one);
let two = yield 222;
console.log(two);
let three = yield 333;
console.log(three);
}
let iterator = gen('aaa'); // 无打印结果
console.log(iterator.next()); //aaa {value: '111', done: false}
console.log(iterator.next('bbb')); //bbb {value: '222', done: false}
console.log(iterator.next('ccc')); //ccc {value: '333', done: false}
console.log(iterator.next('ddd')); //ddd {value: undefined, done: true}
生成器函数实例
function one(){
setTimeout(()=>{
console.log(111)
iterator.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222)
iterator.next();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333)
iterator.next();
},3000)
}
function * gen(){
yield one(); // 函数代码的分隔符
yield two();
yield three();
}
let iterator = gen(); // 无打印结果
iterator.next();
// 111
// 222
// 333
function getUsers(){
setTimeout(()=>{
let data = '用户数据'
// 调用next方法,并且将数据传入
iterator.next(data);
},1000)
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据'
iterator.next(data);
},2000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据'
iterator.next(data);
},3000)
}
function * gen(){
let users = yield getUsers(); // 函数代码的分隔符
console.log(users)
let orders = yield getOrders();
console.log(orders)
let goods = yield getGoods();
console.log(goods)
}
let iterator = gen(); // 无打印结果
iterator.next();
// 用户数据
// 订单数据
// 商品数据
Promise
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作可以获取其成功或失败的结果。
// 实例化Promise对象
const p = new Promise(function(resolve,reject){
setTimeout(function(){
// let data = '数据库中的数据'
// resolve(data)
let err = '数据读取失败'
reject(err)
},1000);
})
// 调用 promise对象的then方法
p.then(function(value){
console.log(value);
},function(reason){
console.error(reason);
})
Promise封装读取文件
const fs = require('fs');
const p = new Promise(function(resolve,reject){
fs.readFile("./resources/为学.mda",(err,data)=>{
// 判断如果失败
if(err) reject(err);
//如果成功
resolve(data);
})
})
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取失败!")
})
Promise封装AJAX
const p = New Promise((resolve,reject) => {
// 创建对象
const xhr = new XMLHttpRequest();
// 初始化
xhr.open("GET","https://api.apiopen.top/getJosn");
// 发送
xhr.send();
// 绑定事件,处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
}else{
reject(xhr.status)
}
}
}
})
p.then(function(value){
console.log(value)
},function(reason){
console.error(reason)
})
Promise.prototype.then 方法
// 创建一个Promise对象
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('用户数据');
},1000)
})
// 调用then方法 then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
// 1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象成功的值
// 2.如果回调函数中返回的结果是promise类型的属性,状态为成功,返回值为对象成功的值,失败即失败的值
const result = p.then(value => {
console.log(value)
// 1. 非promise 对象
// return '231'
// 2. promise 对象
// return new Promise((resolve,reject)=>{
// // resolve('ok');
// reject('error');
// })
// 3.抛出错误
throw ('出错啦!');
}, reason => {
console.warn(reason)
})
//
console.log(result);
// 链式调用
p.then(value=>{
}).then(value=>{
})
catch方法
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject("出错啦!")
},1000)
})
p.catch(function(reason)=>{
console.err(reason)
})
set集合
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for…of… 进行遍历。
集合的属性和方法
- size 返回集合元素的个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回boolean值
- has 检测集合十分包含某个元素,返回boolean值
let arr = [1,2,3,4,5,6,7,4,3,4,2,1]
// 1.数组去重
let result = [...new Set(arr)];
// 2.交集
let arr2 = [2,4,6,8,9,3]
let result = [...new Set(arr)].filter(item =>{
let s2 = new Set(arr2);
if(s2.has(item)){
return true
}else{
return false
}
})
// let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
//cosole.log(result)
// 并集
let union = [...new Set([...arr,...arr2])];
// 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
Map
ES6提供了Map数据结构,它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用扩展运算符和for…of…进行遍历。
Map的属性和方法
- size 返回Map的元素的个数
- set 增加一个新元素,返回当前Map
- get 返回键名对象的键值
- has 检测Map中是否包含某个元素,返回boolean值
- clear 清空集合,返回undefined
// 声明 Map
let m = new Map();
// 添加元素
m.set('name','张三') // Map(1) {'name' => '张三'}
m.set('change',function(){console.log('我们可以改变你')}) // {'name' => '张三', 'change' => ƒ}
let key = { school: '123'}
m.set(key,[1,2,3]) // Map(3) {'name' => '张三', 'change' => ƒ, {…} => Array(3)}
// 删除
m.delete('name') // Map(2) {'change' => ƒ, {…} => Array(3)}
// 遍历
for(let v of m){
console.log(v);
}
// (2) ['change', ƒ]
// (2) [{…}, Array(3)]
// 清空
m.clear()
类 class
// ES5 通过实例化函数
function Phone (brand,price){
this.brand = brand;
this.price = price;
}
// 添加方法
Phone.prototype.call = function(){
console.log('我可以打电话!')
}
// 实例化对象
let Huawei = new Phone('华为',5999)
Huawei.call(); // 我可以打电话!
console.log(Huawei) // Phone {brand: '华为', price: 5999}
// ES6
class Phone {
constructor(brand,price){
this.brand = brand;
this.price = price;
}
call(){
console.log('我可以打电话!')
}
}
let onePuls = new Phone("1+",1999);
console.log(onePuls) // Phone {brand: '1+', price: 1999}
class 静态成员
function Phone(){}
// 静态成员 是属于函数对象的并不属于实例对象
Phone.name = '手机';
Phone.change = function(){
console.log('我可以改变世界')
}
let nokia = new Phone();
console.log(nokia.name); // undefined
nokia.change();// 报错
Phone.prototype.size = '5.5inch' // 放在原型链上的
console.log(nokia.size); // 5.5inch
class Phone{
// 静态属性 属于类而不属于实例对象
static name = "手机";
static change(){
console.log('我可以改变世界')
}
}
let nokia = new Phone();
console.log(nokia.name) // undefined
console.log(Phone.name) // 手机
ES5构造函数继承
// 手机
function Phone(brand,price){
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function(){
console.log('我可以打电话!')
}
function SmartPhone(brand,price,color,size){
Phone.call(this,brand,price);
this.color = color;
this.size = size;
}
SmartPhone.prototype = new Phone;
SmartPhone.prototype.photo = function(){
console.log("我可以拍照")
}
SmartPhone.prototype.playGame= function(){
console.log("我可以玩游戏")
}
const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch')
console.log(chuizi)
ES6 class类的继承
class Phone {
constructor(brand,price){
this.brand = brand;
this.price = price;
}
call(){
cosole.log('我可以打电话!')
}
}
class SmartPhone extends Phone {
constructor(brand,price,color,size){
super(brand,price);
this.color= color;
this.size= size;
}
photo(){
console.log('我可以拍照')
}
playGame(){
console.log('玩游戏')
}
// 子类重写父类方法
call(){
cosole.log('我可以视频通话!')
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','5.5')
console.log(xiaomi) // SmartPhone {brand: '小米', price: 799, color: '黑色', size: '5.5'}
class类中的getter 和setter
class Phone{
get price(){
console.log('价格被读取了')
}
set price(newVal){
console.log('价格被修改了')
}
}
let a = new Phone
console.log(a.price) // 价格被读取了
a.price = 'free' // 价格被修改了
数值的扩展
Number.EPSILON 是JavaScript 表示的最小精度
function equal(a,b){
if(Math.abs(a-b) < Number.EPSILON){
return true;
}else{
return false
}
}
console.log(0.1+0.2===0.3) // false
console.log(equal(0.1+0.2,0.3)) // true
二进制和八进制,十进制,十六进制
let b = 0b1010; // 10
let o = 0o777; // 511
let d = 100; // 100
let x = 0xff; // 255
Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(100/0)); // false
console.log(Number.isFinite(Infinity)); // false
Number.isNaN 检测一个数值是否为NaN,是否为非数字
console.log(Number.isNaN(123)) // false
Number.parseInt Number.parseFloat 字符串转整数
console.log(Number.parseInt('5211314love')); // 5211314
console.log(Number.parseFloat('3.1415926神奇')); //3.1415926
Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5)); // true
console.log(Number.isInteger(2.5)); // false
Math.trunc 将数字的小数部分抹掉
console.log(Math.trunc(3.5)); // 3
Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100)); //1
console.log(Math.sign(0)); //0
console.log(Math.sign(-100)); //-1
对象方法的扩展
// Object.is 判断两个值是否完全相等
console.log(Object.is(120,120)); // true
console.log(Object.is(NaN,NaN)); // true
// Object.assign 对象的合并
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
pass: 'root'
}
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: '张三',
pass: 'iloveyou'
}
console.log(Object.assign(config1,config2)); // {host: 'http://atguigu.com', port: 33060, name: '张三', pass: 'iloveyou'} 后面那个对象属性会覆盖前面已有的对象属性
// 设置原型对象 Object.setPrototypeOf 获取原型对象 Object.getPrototypeOf
const school = {
name:'尚硅谷'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(school,cities);
console.log(school);
//{name: '尚硅谷'}
// name: "尚硅谷"
// [[Prototype]]: Object
// xiaoqu: (3) ['北京', '上海', '深圳']
// [[Prototype]]: Object
console.log(Object.getPrototypeOf(school))
//{xiaoqu: Array(3)}
// xiaoqu: (3) ['北京', '上海', '深圳']
// [[Prototype]]: Object
模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
模块化的好处
模块化的优势
- 防止命名冲突
- 代码复用性高
- 高维护性
模块化规划产品
ES6之前的模块化规范有
- CommonJS => NodeJS、 Browserify
- AMD => requireJS
- CMD => seaJS
ES6 模块化语法
模块功能主要由两个命令构成:export和import
- export 命令用于规定模块的对外接口
- import命令用于输入其他模块提供的功能
// m1.js 分别暴露
export let school = '大学'
export function teach(){
console.log("我们可以教你开发技能!")
}
// m2.js 统一暴露
let school = '大学'
function teach(){
console.log("我们可以教你开发技能!")
}
export{school,findJob};
// m3.js 默认暴露
export default {
let school = '大学'
function teach(){
console.log("我们可以教你开发技能!")
}
}
// index.html
// 通用的导入方式
// 引入m1.js 模块内容
import * as m1 from "./src/js/m1.js";
// 引入m2.js 模块内容
import * as m2 from "./src/js/m2.js";
// 引入m3.js 模块内容
import * as m3 from "./src/js/m3.js";
m3.default.change(); // 我们可以教你开发技能!
// 结构赋值的形式
import {school,teach} from "./src/js/m1.js"
import {school as guigu} from "./src/js/m2.js" // as guigu 别名
import {default as m3} from "./src/js/m3.js"
// 简便形式 针对默认暴露
import m3 from "./src/js/m3.js"
ES7新特性
Array.prototype.includes
用来检测数组中是否包含某个元素,返回布尔类型值
指数操作符
用来实现幂运算,功能与Math.pow结果相同
// includes indexOf(查找索引)
const mingzhu= ['西游记','三国演义','红楼梦','水浒传'];
// 判断
console.log(mingzhu.includes('西游记')); // true
// **
console.log(2 ** 10); // Math.pow(2,10) // 1024 2的10次方
ES8
async和await
async和await两种语法结合可以让异步代码像同步代码一样
async
- 返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
async function fn(){
return '嗯嗯' // 返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象
// 抛出错误 ,返回的结果是一个失败的Promise
// throw new Error('出错啦!')
}
const result = fn();
console.log(result)
//Promise {<fulfilled>: '嗯嗯'}
// [[Prototype]]: Promise
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: "嗯嗯"
await
- await必须卸载async函数中
- await右侧的表达式一般为promise对象
- await返回的是promise成功的值
- await的promise失败了。就会抛出异常,需要通过try…catch捕获处理
const p = new Promise((resolve,reject)=>{
resolve('成功的值!')
})
async function main(){
let result = await p;
console.log(result);
}
//
main(); //成功的值!
const p = new Promise((resolve,reject)=>{
reject('失败啦')
})
async function main(){
try{
let result = await p;
console.log(result);
}catch (e){
console.log(e)
}
}
//
main(); //失败啦!
async与await结合发送AJAX请求
function sendAJAX(url) {
return new Promise((resolve,reject) => {
// 创建对象
const x = new XMLHttpRequest();
// 初始化
x.open('GET',url);
// 发送
x.send();
// 事件绑定
x.onreadystatechange = function () {
if(x.readyState === 4) {
if(x.status >= 200 && x.status <300) {
// 成功啦
resolve(x.response);
}else{
// 如果失败
reject(x.status)
}
}
}
})
}
sendAJAX('https://api/getJoke').then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
// async 与await测试
async function main(){
let result = await sendAJAX("https://api/getJoke");
console.log(result);
}
main()
ES8对象方法扩展
// 声明对象
const school = {
name: "张三",
cities:['重庆','上海','深圳'],
xueke: ['前端','java','大数据','运维']
};
// 获取对象所有的键
console.log(Object.keys(school))// ['name', 'cities', 'xueke']
console.log(Object.values(school))// ['张三', Array(3), Array(4)]
console.log(Object.entries(school))
//0: (2) ['name', '张三']
//1: (2) ['cities', Array(3)]
//2: (2) ['xueke', Array(4)]
// 创建 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:'你好',// 设置值
writable:true,//是否可写
configurable:true,//是否可以删除
enumerable:true//是否可以枚举
}
})
ES9 正则扩展-命名捕获分组
// 声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// 提取url 与标签文本
const reg = /<a href="(.*)">(.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
// ['<a href="http://www.atguigu.com">尚硅谷</a>', 'http://www.atguigu.com', '尚硅谷', index: 0, input: '<a href="http://www.atguigu.com">尚硅谷</a>', groups: undefined]
// 声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
// 提取url 与标签文本
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
//0: "<a href=\"http://www.atguigu.com\">尚硅谷</a>"
//1: "http://www.atguigu.com"
//2: "尚硅谷"
//groups: {url: 'http://www.atguigu.com', text: '尚硅谷'}
//index: 0
//input: "<a href=\"http://www.atguigu.com\">尚硅谷</a>"
正则扩展 -反向断言
let str = 'js283773你回到789啦啦啦';
// 正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result);
//['789', index: 11, input: 'js283773你回到789啦啦啦', groups: undefined]
//0: "789"
//groups: undefined
//index: 11
//input: "js283773你回到789啦啦啦"
//length: 1
// 反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result)
//['789', index: 11, input: 'js283773你回到789啦啦啦', groups: undefined]
//0: "789"
//groups: undefined
//index: 11
//input: "js283773你回到789啦啦啦"
//length: 1
ES10 - 对象的扩展方法
// Object.entries的逆向操作 es8
//二维数组
const result = Object.fromEntries([
['name','尚硅谷'],
['xueke','java,大数据,前端']
]);
console.log(result) //{name: '尚硅谷', xueke: 'java,大数据,前端'}
trimStart 与trimEnd
删除字符串前面或者后面的空格
let str = ' abc '
str.trimStart() //'abc '
str.trimEnd() //'abc'
flat和flatMap
flat,将多维数组转换为低位数组
let arr = [1,2,3,4,[5,6]]
console.log(arr.flat()) // [1, 2, 3, 4, 5, 6]
let arr1 = [1,2,3,4,[5,6,[7,8,9]]]
console.log(arr1.flat()) // [1, 2, 3, 4, 5, 6, Array(3)]
console.log(arr1.flat(2)) // [1, 2, 3, 4, 5, 6, 7, 8, 9] 深度为2 打开两层
// flatMap 相当于是flat和map 的结合
let arr2 = [1,2,3,4]
let result = arr2.flatMap(item => [item * 10]);
console.log(result) //[10, 20, 30, 40]
Symbol.prototype.description
let s = Symbol('尚硅谷');
console.log(s.description) //尚硅谷
ES11 私有属性
class Person{
// 公有属性
name;
// 私有属性
#age;
#weight;
// 构造方法
constrctor(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: undefined, #age: undefined, #weight: undefined}
console.log(girl.#age); // 报错 只能出现在类里面,不能出现在类外面
intro()
// 小红
// 18
// 45kg
Promise.allSettled
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('商品数据1')
},1000)
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('出错啦')
},1000)
})
const result = Promise.allSettled([p1,p2]);// allSettled两个Promise对象返回值一个是resolve就返回成功
console.log(result)
// Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: Array(2)
// 0: {status: 'fulfilled', value: '商品数据1'}
// 1: {status: 'rejected', reason: '出错啦'}
// length: 2
// [[Prototype]]: Array(0)
```javascript
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('商品数据1')
},1000)
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('出错啦')
},1000)
})
const res = Promise.all([p1,p2]); // all两个Promise对象返回值都必须是resolve才返回成功
console.log(res)
//Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "rejected"
// [[PromiseResult]]: "出错啦"
可选链操作符
function main(config){
const dbHost = config?.db?.host; // config有 找到config.db,确认有,找到config.db.host
console.log(dbHost);
}
main({
db:{
host:'192.168.1.100',
username:'root'
},
cache:{
host:'192.168.1.100',
username:'root'
}
})
动态import
按需引入
// import * as m1 from "./hello.js"; //静态引入
const btn = document.getElementById('btn');
btn.onclick = function(){
import('./hello.js').then(module => { //动态引入,按需加载
module.hello();
})
}
BigInt
//大整形
let n = 521n;
console.log(n,typeof(n)); //521n 'bigint'
// 函数
let n = 123;
console.log(BigInt(n));
console.log(BigInt(1.2));
// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);//9007199254740991
console.log(max + 1);//9007199254740992
console.log(BigInt(max) + 1);//报错
console.log(BigInt(max) + BigInt(1));//9007199254740992
globalThis
无论什么环境下指向全局对象
console.log(globalThis)//Window {}