ES6(ECMAScript6)-ES11 从入门到修仙

ES6:ECMAScript6

 一、ES6新特性

1.let变量声明以及声明特性

1.1 let

let 关键字用来声明变量,使用 let 声明的变量有以下几个特点:

let a;
let b,c,d;
let e = 100;
let f = 521,g= 'iloveyou',h = [];

1.变量不能重复声明

let star = '离歌笑';
let star = '李逍遥';

2.块级作用域 全局,函数,eval

//if else while  for
{
    let girl = '赵灵儿';
}
console.log(girl);

3.不存在变量提升

console.log(song);
let song = '仙剑奇侠传';

4.不影响作用域链

{
    let school = '仙一';
    function fn(){
        console.log(school);
    }
    fn();
}

1.2案例

需求:点击div更换背景颜色




    
    Title


    

 ES6(ECMAScript6)-ES11 从入门到修仙_第1张图片

1.3const

const 关键字用来声明常量,const 声明有以下特点:
(常量的含义是指向的对象不能修改,但是可以改变对象内部的属性)

1.一定要赋初始值

const A;

2.一般变量使用大写(潜规则)

const a = 100;

3.常量的值不能修改

SCHOOL = 'LIGEXIAO';

4.块级作用域

{
     const PLAYER = 'UZI';
}
console.log(PLAYER);

5.对于数组和对象的元素修改,不算做对常量的修改,不会报错

    const TEAM = ['UZI','MXLG','Ming','Letme'];
    TEAM.push('LGX');
    console.log(TEAM);

 6.不允许重复声明

const FRUIT = "apple" 
const FRUIT = "apple" // 报错,不可重复声明

1.4解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
使用场景:频繁使用对象方法、数组元素,就可以使用解构赋值形式;

1.数组的结构

const F4 = ['李逍遥','林月如','赵灵儿','刘晋元'];
let[li,lin,zhao,liu] = F4;
console.log(li);
console.log(lin);
console.log(zhao);
console.log(liu);

 2.对象的解构

const li = {
    name:'离歌笑',
    age:'18',
    sing:function(){
        console.log('六月的雨');
    }
}
let{name,age,sing} = li;
console.log(name);
console.log(age);
console.log(sing);
sing();

注意:

  • 在let{name,age,sing} = li的{ } 中,里面的变量名需要和对象中的属性名相同
  • 可以通过let {sing} = li只获取里面的sing方法,之后也是通过sing()调用

 2. 模板字符串

使用一对反引号 ` ` 声明的字符串,特性如下:

 1.声明

let str = `一曲离歌笑江湖`;
console.log(str,typeof str);//一曲离歌笑江湖 string

2.里面可以直接使用换行

let str = ` 
  • 离歌笑
  • 李逍遥
  • 赵灵儿
`; console.log(str);

3.变量拼接(替换/插入)

使用${变量名}定位插入的元素位置

let name = '离歌笑';
let out =  `一曲${name}江湖`;
console.log(out);//一曲离歌笑江湖

3. 对象的简化写法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的书写更加简洁

let name = '离歌笑';
let sing = function(){
    console.log('一曲离歌啸江湖');
}

 原来:

const cos = {
    name:name,
    sing:sing,
    ligexiao:function(){
        console.log('一曲离歌啸江湖');
    }
} 

ES6:

const cos = {
    name,
    sing,
    ligexiao(){
        console.log('行如止水,心无旁骛');
    }
}

4. 箭头函数

ES6允许使用箭头 =>定义函数

 函数声明:

//  let fn = function() {
// 		...
//  }

let fn = (a,b) => {
	return a + b
}
// 调用函数
console.log(fn(2,3))  // 5

1.this是静态的,this始终指向函数声明时所在作用域下的this的值

function getName(){
    console.log(this.name);
}
let getName2 = ()=>{
    console.log(this.name);
}
window.name = '离歌笑';
const school = {
    name :'LIGEXIAO',
}
//直接调用
getName();//离歌笑
getName2();//离歌笑

//call方法调用
getName.call(school);//LIGEXIAO
getName2.call(school);//离歌笑

2.不能作为构造函数实例化对象

let Person =(name,age)=>{
    this.name = name;
    this.age = age;
}
let me = new Person('ligexiao','30');
console.log(me);//Uncaught TypeError: Person is not a constructor

3.不能使用arguments 变量

let fn = () =>{
    console.log(arguments);//Uncaught ReferenceError: arguments is not defined
}
fn(1,2,3);

4.箭头函数的简写
(1) 省略小括号,当形参有且只有一个的时候可以省略小括号。

// let add = (n) => {
// 	 console.log(n + n)
// }
// add(3)  // 6

// 简写:
let add = n => {
	console.log(n + n)
}
add(3)  // 6

(2) 省略花括号 { },仅当函数语句只有一条语句时。此时,'return' 也需要省略,结果即是返回值

let pow = n => n * n
console.log(pow(8))    // 64

实践练习




    
    
    
    8.箭头函数练习
    


    
    

 箭头函数适合与this无关的回调、定时器、数组的方法回调

箭头函数不适合与this有关的回调,事件回调,对象的方法


5. 函数参数默认值

ES6允许给函数参数赋值初始值

特性:

  1. 可以给形参赋初始值,一般位置要靠后(潜规则)
function add(a,b,c=12){
    return a+b+c; 
}
let result = add (1,2) 
console.log(result) // 15

 如果上面代码没有给 形参c赋初始值,则执行add (1,2)时,形参c没有对应的参数,默认为NaN,所以add (1,2)的执行结果为NaN

 2.与解构赋值结合

function ap({host='127.0.0.1', username, password, port}){
    console.log(host,username,password,port)    // 
}
ap({
	host: 'localhost',
    username:'admin',
    password:'000000',
    port:3000
 })
 // 执行结果:localhost admin 000000 3000

6. rest参数

  • ES6引入rest参数,用于获取函数的实参,用来代替arguments

  • rest参数:以...为前缀,例如下面的...args

 原来的arguments

function date(){
    console.log(arguments);
}
date('离歌笑','李逍遥','赵灵儿');//Arguments(3) ['离歌笑', '李逍遥', '赵灵儿', callee: ƒ, Symbol(Symbol.iterator): ƒ]

现在的rest参数

function date(...arg){
    console.log(arg);
}
date('离歌笑','李逍遥','赵灵儿');//['离歌笑', '李逍遥', '赵灵儿']

rest参数必须要放到参数最后

function fn(a,b,...arg){
    console.log(a);
    console.log(b);
    console.log(...arg);
}
fn(1,2,3,4,5,6,7);//1 
                    // 2
                    //3 4 5 6 7

7. 扩展运算符

扩展运算符... ,能将数组转换为逗号分隔的参数序列

const tfboys=['易烊千玺','王源','王俊凯']
function show(){
    console.log(arguments) 
}
show(tfboys)    // 一个参数,数组:['易烊千玺', '王源', '王俊凯']
show(...tfboys) //0: "易烊千玺"  1: "王源" 2: "王俊凯"

ES6(ECMAScript6)-ES11 从入门到修仙_第2张图片

 应用:

1.数组的合并

const arr1 = ['李逍遥','离歌笑'];
const arr2 = ['林月如','赵灵儿'];
// const arr = arr1.concat(arr2);//['李逍遥', '离歌笑', '林月如', '赵灵儿']
const arr = [...arr1,...arr2];
console.log(arr);//['李逍遥', '离歌笑', '林月如', '赵灵儿']

 2.数组的克隆

const arr3 = ['李逍遥', '离歌笑', '林月如', '赵灵儿'];
const arr4 = [...arr3];//['李逍遥', '离歌笑', '林月如', '赵灵儿']
console.log(arr4);//['李逍遥', '离歌笑', '林月如', '赵灵儿']

如果数组里面有引用类型的数据,则整个为浅拷贝 ;否则,就是完全拷贝

const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr);// [div, div, div]

8. Symbol


语法

直接使用 Symbol() 创建新的 symbol 类型,并用一个可选的字符串作为其描述。

Symbol([description])

description (可选) 字符串类型。对symbol的描述,可用于调试但不是访问symbol本身。请注意,即使传入两个相同的字符串,得到的 symbol 也不相等。

const symbol1 = Symbol();
const symbol2 = Symbol(42);

 Symbol()与Symbol.for()的区别

Symbol() :调用相同的symbol多次,会生成多个symbol

Symbol.for():调用相同的symbol多次,仍只会执行第一次的symbol

Symbol.for(key) 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。

key:一个字符串,作为 symbol 注册表中与某 symbol 关联的键(可重复调用)

Symbol.for访问的是一个全局的submbol表,如果有了就访问相应对象,没有就重新创建

Symbol.keyFor()方法:
此方法会获取对应Symbol值的键。

全局定义拿得到symbol的值,普通定义拿不到

let cms = Symbol.for('lgx');//全局定义拿得到symbol的值
console.log(Symbol.keyFor(cms));//lgx
let lxy = Symbol('lxy');//普通定义拿不到
console.log(Symbol.keyFor(lxy));//undefined

 原来:(内容相同使用[]读取内容只能读取到第一个)

let user1 = '离歌笑';
let user2 = '离歌笑';
let grade = {
    [user1]:{js:100,css:89},
    [user2]:{js:50,css:26}
};
console.log(grade);

ES6(ECMAScript6)-ES11 从入门到修仙_第3张图片

现在

// let user1 = '离歌笑';//{js: 100, css: 89}
// let user2 = '离歌笑';
let user1 = {
    name:'离歌笑',
    key:Symbol(),
}
let user2 = {
    name:'离歌笑',
    key:Symbol(),
}
let grade = {
    [user1.key]:{js:100,css:89},
    [user2.key]:{js:50,css:26}
};
console.log(grade[user1.key]);//{js: 100, css: 89}

Symbol取值和赋值都要加[]

私有属性

对象,属性如果不想公布到外部可以用symbol

由于任何两个 symbol 都是不相等的,在 JavaScript 里可以很方便地用来模拟私有属性。symbol` 不会出现在 Object.keys() 的结果中,因此除非你明确地 export 一个 symbol,或者用 Object.getOwnPropertySymbols() 函数获取,否则其他代码无法访问这个属性。

 Object.keys()返回属性key,但不包括不可枚举的属性
Reflect.ownKeys()返回所有属性key

let symbol = Symbol("一曲离歌笑江湖");
let lgx = {
    name:'李逍遥',
    [symbol]:'离歌笑',
}
// for (const key in lgx)//普通遍历遍历不了symbol的值
// {
//     console.log(key);
// }
// for(const key of Object.getOwnPropertySymbols(lgx)){//只能遍历到symbol类型
//     console.log(key);
// }
// for(const key of Reflect.ownKeys(lgx))//返回所有属性key
// {
//     console.log(key);
// }

let site = Symbol('一曲离歌啸江湖');
class User{
    constructor(name){
        this.name = name;
        this[site] = '离歌笑';
    }
    getName(){
        return `${this[site]} ${this.name}`;
    }
}
let lxy = new User('绿巨人');
// console.log(lxy.getName());
// for(let key in lxy)
// {
//     console.log(key);
// }

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。

  • Symbol的值是唯一的,用来解决命名冲突的问题

  • Symbol值不能与其他数据进行运算

  • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

特性:

  1. 创建
//创建Symbol
let s = Symbol();
// console.log(s,typeof s);//Symbol() 'symbol'
let s2 = Symbol('离歌笑');
let s3 = Symbol('离歌笑');
console.log(s2===s3);//false
//Symbol.for 创建
let s4 = Symbol.for("离歌笑");
let s5 = Symbol.for("离歌笑");
console.log(s4===s5);//true

 2.不能与其他数据进行运算(不可运算、比较)

let result = s+100;
let result = s>100;
let result = s+s;//Uncaught TypeError: Cannot convert a Symbol value to a number

3.数据类型的种类

字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined),Symbol

应用:

  1. 给对象添加方法方式一:
let game= {
    name:'俄罗斯方块',
    up:function(){
        console.log('向上');
    },
    down:function(){
        console.log('向下');
    }
}
//声明一个对象
let methods = {
    up:Symbol(),
    down:Symbol(),
};
game[methods.up] = function(){
    console.log('我可以改变形状');
}
game[methods.down] = function(){
    console.log('我可以快速下降!!!');
}
console.log(game);//{name: '俄罗斯方块', up: ƒ, down: ƒ, Symbol(): ƒ, Symbol(): ƒ}
console.log(game[methods.down]());//我可以快速下降!!!

 2.给对象添加方法方式二:

let  youxi = {
    name:'离歌笑',
    [Symbol('lgx')]:function(){
        console.log('一曲离歌笑江湖');
    },
    [Symbol('lxy')]:function(){
        console.log('行如止水,心无旁骛');
    }
}
console.log(youxi);//{name: '离歌笑', Symbol(lgx): ƒ, Symbol(lxy): ƒ}

 想读取Symbol方法的内容

let lgx = Symbol('lgx');
let lxy = Symbol('lxy');
let  youxi = {
    name:'离歌笑',
    lgx:function(){
        console.log('一曲离歌笑江湖');
    },
    lxy:function(){
        console.log('行如止水,心无旁骛');
    }
}
youxi.lxy()//行如止水,心无旁骛

symbol 内置属性

1.Symbol.hasInstance(自己控制类型检测)

//自己控制类型检测
class Person{
    static [Symbol.hasInstance](param){
        console.log(param);
        console.log('我被用来检测类型了');
        return false;
    }
}
let o = {};
console.log(o instanceof Person);

 2.Symbol.isConcatSpreadable(该属性决定了当前对象作为concat的参数时是否可以展开)

const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable]=false;
console.log(arr.concat(arr2));

9. 迭代器

迭代器( lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。

    ES6创造了一种新的遍历命令for…of循环,lterator接口主要供 for…of消费
    原生具备iterator接口的数据(可用for of遍历)

 for ... of for ... in

for(let v in xiyou){
    console.log(v);//0 1 2 3
}
//使用for...of遍历数组
for(let v of xiyou){
    console.log(v);//李逍遥 赵灵儿 林月如 刘晋元
}

迭代器原理

  1. 创建一个指针对象,指向数据结构的起始位置
  2. 第一次调用next()方法,指针自动指向数据结构第一个成员
  3. 接下来不断调用next(),指针一直往后移动,直到指向最后一个成员
  4. 每次调用next()返回一个包含valuedone属性的对象
const xiyou = ['李逍遥','赵灵儿','林月如','刘晋元'];
//使用for...of遍历数组
// for(let v of xiyou){
//     console.log(v);//李逍遥 赵灵儿 林月如 刘晋元
//     for in保存的是键名,for of保存的是键值
// }
let iterator = xiyou[Symbol.iterator]();
//调用对象的iterator方法,done: true,指针指向最后一个,结束
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}
  • done的值为true的时候表示循环完成了
  • 需要自定义遍历数组的时候,要想到迭代器

 实践练习




    
    
    
    17.迭代器自定义遍历对象


    


10. 生成器

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同,是一种特殊的函数

    一个generator看上去像一个函数,但可以返回多次
    generator和函数不同的是,generator由function * 定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。

 回调地狱

setTimeout(()=>{
    console.log('1秒');
    setTimeout(()=>{
        console.log('2秒');
        setTimeout(()=>{
            console.log('3秒');
            setTimeout(()=>{
                console.log('4秒');
                setTimeout(()=>{
                    console.log('5秒');
                },5000)
            },4000)
        },3000)
    },2000)
},1000)
function * generator (){    //函数名和function中间有一个 * 
    yield '耳朵'      //yield是函数代码的分隔符
    yield '尾巴' 
    yield '真奇怪' 
}
let iterator = generator() 
console.log(iteretor.next())  
//{value:'耳朵',done:false} next()  // 执行第一段,并且返回yield后面的值
console.log(iteretor.next())  //{value:'尾巴',done:false}
console.log(iteretor.next())  //{value:'真奇怪',done:false}
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

// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());

//遍历
for(let v of iterator)
{
    console.log(v);111 一只没有耳朵 222 一只没有眼睛 333 真奇怪444
}

1. 生成器函数的参数传递

第二次调next方法传入的实参将作为第一个yield语句的整体返回结果

当前next方法传入的实参将作为 上一个yield语句的整体返回结果

function * gen(args){
console.log(args) //AAA
let one = yield 111  //111 (将 yield 111 返回的值赋给one)
console.log(one) //BBB
let two = yield 222 //222
console.log(two) //CCC
let three = yield 333 //333
console.log(three) //DDD
}

let iterator = gen('AAA') 
console.log(iterator.next()) 
console.log(iterator.next('BBB'))   //next中传入的BBB将作为yield 111的返回结果
console.log(iterator.next('CCC'))   //next中传入的CCC将作为yield 222的返回结果
console.log(iterator.next('DDD'))   //next中传入的DDD将作为yield 333的返回结果

 ES6(ECMAScript6)-ES11 从入门到修仙_第4张图片

2. 实例1:用生成器函数的方式解决回调地狱问题

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() //111
    yield two() //222
    yield three() /333
}

let iterator = gen() 
iterator.next() 

3.实例2:模拟异步获取数据

异步编程:文件操作 网络操作(ajax,request) 数据库操作 定时器

//模拟获取 用户数据 订单数据 商品数据
function getUsers(){
    setTimeout(()=>{
        let data = '用户数据';
        iterator.next(data);
    },1000)
}
function getOrders(){
    setTimeout(()=>{
        let data = '订单数据';
        iterator.next(data);
    },1000)
}
function getGoods(){
    setTimeout(()=>{
        let data = '商品数据';
        iterator.next(data);
    },1000)
}

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();

11. Promise

Promise是ES6引入的异步编程的新解决方案。语法上 Promise是一个构造函数,用来封装异步操作并可以获取其成功失败的结果。

 const p = new Promise((resolve, reject) => {
        setTimeout(()=>{
            let data='数据库数据'
            // resolve(data) 
            reject(data) 
        })
    })

p.then(function (value){   // 成功则执行第一个回调函数
    console.log(value)
},function (reason){      // 失败则执行第二个
    console.error(reason)
})

 Promise读取文件

//1.引入fs模块
const fs = require('fs');
fs.readFile('./resource/content.txt',function(err,data){
    if(err)throw err;
    console.log(data); 
})


const p = new Promise(function(resolve,reject){
    require('fs').readFile('./resource/content.txt',function(err,data){
        if(err) reject(err);
        resolve(data);
    })
})
p.then(function(value){
    console.log(value.toString())
},function(reason){
    console.error('error真成功');
})   

Promise封装Ajax请求

//接口地址:https://api.apiopen.top/getJoke
const p = new Promise(function(resolve,reject){
    //1.创建对象
    const xhr = new XMLHttpRequest();
    //2.初始化
    xhr.open('GET', 'https://api.apiopen.top/geoke');
    //3.发送
    xhr.send();
    //4.绑定事件,处理响应结果
    xhr.onreadystatechange = function(){
        //判断
        if(xhr.readyState === 4)
        {
            //判断响应状态码 200-299
            if(xhr.status >= 200 && xhr.status < 300)
            {
                //表示成功
                resolve(xhr.response);
            }
            else{
                //表示失败
                reject(xhr.status);
            }
        }
    }
})
p.then((value)=>{
    console.log(value);
},
(reason)=>{
    console.error(reason);
})

Promise.then()方法

const p =new Promise((resolve, reject) =>{
    setTimeout(() => {
        resolve('用户数据') 
    })
});

//then()函数返回的实际也是一个Promise对象
//1.当回调后,返回的是非Promise类型的属性时,状态为fulfilled,then()函数的返回值为对象的成功值,如reutnr 123,返回的Promise对象值为123,如果没有返回值,是undefined

//2.当回调后,返回的是Promise类型的对象时,then()函数的返回值为这个Promise对象的状态值

//3.当回调后,如果抛出的异常,则then()函数的返回值状态也是rejected
let result = p.then(value => {
    console.log(value)
     //1.非Promise类型的属性
    // return 123 
     //2.是Promise对象
    // return new Promise((resolve, reject) => {
          // resolve('ok');
          // reject('error');//rejected(失败)
    // })
    //3.抛出错误
    // throw new Error('出错啦!');
    // throw '出错啦!!!';
},reason => {
    console.log(reason)
})
console.log(result) 

 链式回调

p.then(value=>{}).then(value=>{})

 案例 Promise读取多个文件

//引入fs模块
const fs = require('fs');
//回调地狱
// fs.readFile('./resource/草.txt',(err,data1)=>{
//     fs.readFile('./resource/无题.txt',(err,data2)=>{
//         fs.readFile('./resource/题雁塔.txt',(err,data3)=>{
//             let result = `${data1} 
//             ${data2}  
//             ${data3} `;
//              console.log(result.toString());
//         })
//     })
// })
const p = new Promise((reslove,reject)=>{
    fs.readFile('./resource/草.txt',(err,data)=>{
        reslove(data);
    })
})
p.then(value=>{
    return  new Promise((reslove,reject)=>{
        fs.readFile('./resource/无题.txt',(err,data)=>{
            reslove([value,data]);
        })
    })
}).then(value=>{
    return  new Promise((reslove,reject)=>{
        fs.readFile('./resource/题雁塔.txt',(err,data)=>{
            //压入
            value.push(data);
            reslove(value);
        })
    })
}).then(value=>{
    console.log(value.join('\r\n'));
})

Promise.catch()方法

const p = new Promise((resolve, reject) => {
    setTimeout(()=>{
        reject('出错啦')
    },1000)
})

p.catch(reason => {
    console.log(reason)
})

12. 集合

12.1 Set

ES6提供了新的数据结构set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用「扩展运算符』和「 for…of…』进行遍历

集合的属性和方法:

  • .size返回集合的元素个数
  • .add()增加一个新元素,返回当前集合
  • .delete()删除元素,返回boolean值
  • .has()检测集合中是否包含某个元素,返回boolean值
let s = new Set();
let s2 = new Set(['A','B','C','D'])

//元素个数
console.log(s2.size) 

//添加新的元素E
s2.add('E') 

//删除元素A
s2.delete('A')

//检测是否有 C
console.log(s2.has('C')) 

//清空
s2.clear()

console.log(s2) 

 应用:

let arr = [1,2,3,4,5,4,3,2,1];
//1.数组去重
// let result = [...new Set(arr)];
// console.log(result);//[1, 2, 3, 4, 5]
//2.交集
let arr2 = [4,5,6,5,6];
let s2 = new Set(arr2);//4 5 6
// let result  = [...new Set(arr)].filter(item=>{
//     if(s2.has(item))
//     {
//         return true;
//     }
//     else{
//         return false;
//     }
// })
let result = [...new Set(arr)].filter(item=>s2.has(item))
console.log(result);//[4, 5]
//3.并集
let union = [...new Set([...arr,...arr2])];
console.log(union);//[1, 2, 3, 4, 5, 6]
//4.差集
let diff = [...new Set(arr)].filter(item=>!(s2.has(item)))
console.log(diff);// [1, 2, 3]

12.2 Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』和「for…of…』进行遍历。

Map的属性和方法:

  • .size 获取Map的键值对数量(最外层)
  • .set(key,value) 添加键值对
  • .delete(key) 删除键为key的键值对
  • .get(key) 获取键为key的值
  • for...of 遍历里面的每一个键值对
let m = new Map();
//添加元素
m.set('name','离歌笑');
m.set('lgx',function(){
    console.log('我可以改变世界');
})
let key = {
    school:'xianyi'
}
m.set(key,['杭州','长安','仙灵']);

//size
console.log(m.size);

//删除键为name的键值对,会返回修改后的Map集合
// m.delete(key);
m.delete('name');

//获取
console.log(m.get('lgx'));
console.log(m.get(key));

//清空
// m.clear();

console.log(m);
//遍历里面的每一个键值对
for(let v of m)
{
    console.log(v);
}

13. Class

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

//ES5的构造函数
function Phone(brand,price){
    this.brand = brand;
    this.price = price;
}    
Phone.prototype.call = function(){
    console.log('我可以打电话');
}
//实例化对象
let Huawei = new Phone('华为','2000');
console.log(Huawei);
Huawei.call();

//ES6的构造函数 Class
class iPhone{
    //构造方法,名字不能修改
    constructor(brand,price){
        this.brand = brand;
        this.price = price;
    }
    //方法必须使用该语法,不能使用ES5的对象完整形式
    call(){
        console.log('我可以打电话');
    }
}
let onePlus = new iPhone("1+",1999);
onePlus.call();
console.log(onePlus);

 结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第5张图片

 13.1 静态成员

ES5静态成员

function Phone(){} 
Phone.iname='手机';//静态成员,不能被实例化对象调用
Phone.change= function(){
    console.log("我可以改变世界,但是先要改变自己");
}   
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(Phone.iname);//手机
Phone.change();//我可以改变世界,但是先要改变自己
console.log(nokia.iname);//undefined
console.log(nokia.size);//5.5inch

ES6静态成员

class Phone{
    // 声明静态成员变量
    static name = '手机';
    static change(){
        console.log("我可以改变世界,但是先要改变自己");
    }
}
let nokia = new Phone();
console.log(nokia.name);//undefined
console.log(Phone.name);//手机

13.2 构造函数继承

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();
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的原型对象
SmartPhone.constructor = SmartPhone;
SmartPhone.prototype.photo = function(){
    console.log('我可以拍照');
}
SmartPhone.prototype.playGame = function(){
    console.log('我可以玩游戏');
}

let chuizi = new SmartPhone('chuizi',2499,'黑色','5.5inch');
console.log(chuizi);

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第6张图片

13.3 Class类继承

class Phone{
    constructor(brand,price){
        this.brand = brand;
        this.price = price;
    }
    call(){
        console.log("我可以打电话");
    }
}
class SmartPhone extends Phone{
    constructor(brand,price,color,size){
        super(brand,price);//Phone.call(this,brand,price)
        this.color = color;
        this.size = size;
    }
    photo(){
        console.log('我可以拍照');
    }
    playGame(){
        console.log('我可以玩游戏');
    }
}
let xiaomi = new SmartPhone('小米',1999,'黑色','4.7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第7张图片

 13.4 子类对父类方法的重写

class Phone{
    constructor(brand,price){
        this.brand = brand;
        this.price = price;
    }
    call(){
        console.log("我可以打电话");
    }
}
class SmartPhone extends Phone{
    constructor(brand,price,color,size){
        super(brand,price);//Phone.call(this,brand,price)
        this.color = color;
        this.size = size;
    }
    photo(){
        console.log('我可以拍照');
    }
    playGame(){
        console.log('我可以玩游戏');
    }
    //重写!!!
    call(){
        console.log('我可以视频通话');
    }
}
let xiaomi = new SmartPhone('小米',1999,'黑色','4.7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

 结果:

 13.5 get和set设置

class Phone{
    get price(){
        console.log('价格属性被读取了');
        return '10000yuan';
    }
    set price(newVal){
        console.log('价格属性被修改了');
    }
}
//实例化对象
let s = new Phone();
console.log(s.price);//10000yuan
s.price = "free";

  结果:


14 数值扩展

// Number.EPSILON是 JavaScript的最小精度,属性的值接近于 2.22044...E-16
function equal(a,b){
    if(Math.abs(a-b)

结果:

 ES6(ECMAScript6)-ES11 从入门到修仙_第8张图片


15.对象方法扩展

//1.Object.is 判断两个值是否完全相等
console.log(Object.is(120,120));//===  //true
console.log(Object.is(isNaN,isNaN));//===  //true
console.log(NaN===NaN);//false

//2.Object.assign 对象的合并
const config1={
host:'localhost',
port:'3306',
name:'root',
pass:'root',
test:'test'
}
const config2={
host:'http://xianyi.com',
port:'33060',
name:'xianyi.com',
pass:'lixiaoyao',
}
console.log(Object.assign(config1,config2));//{host: 'http://xianyi.com', port: '33060', name: 'xianyi.com', pass: 'lixiaoyao', test: 'test'}

//3.Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const school = {
name:'离歌笑'
}
const cities = {
renming:['李逍遥','赵灵儿','林月如']
}
Object.setPrototypeOf(school,cities);
console.log(Object.getPrototypeOf(school));//{renming: Array(3)}
console.log(school);//{name: '离歌笑'}


16. 模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

1. 模块化的好处:

  • 防止命名冲突
  • 代码复用
  • 高维护性
  • 模块化规范产品

2. ES6之前的模块化规范有:

  • CommonJS ====> NodeJS、Browserify
  • AMD ====> requireJS
  • CMD ====> seaJS

3. 语法:

  • 模块功能主要有两个命令构成:exportimport
  • export命令用于规定模块的对外接口
  • import命令用于输入其他模块提供的功能

 16.1 暴露语法

16.1.1.分别暴露

// 下面js代码放在./js/m1.js文件中
//分别暴露
export let school = '离歌笑';
export function teach(){
    console.log('一曲离歌笑江湖');
}

 结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第9张图片

16.1.2. 统一暴露

let school = '清华大学';
function findjob(){
    console.log('找工作吧');
}
//统一暴露
export {school, findjob}

结果:
ES6(ECMAScript6)-ES11 从入门到修仙_第10张图片

 16.1.3. 默认暴露(多变量暴露)

//默认暴露 export default
export default {
    school:'清华大学',
    change:function(){
        console.log('可以改变人的一生!')
    }
}

结果:
ES6(ECMAScript6)-ES11 从入门到修仙_第11张图片

16.2 引入语法

16.2.1. 通用导入方式

import * as m1 from "./js/m1.js"
import * as m2 from "./js/m2.js"
import * as m3 from "./js/m3.js"

 16.2.2. 解构赋值方式

import {school,teach} from "./js/m1.js";
import {school as s ,findJob} from "./js/m2.js";
import {default as m3} from "./js/m3.js";
console.log(school,teach);
console.log(s,findJob);
console.log(m3);

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第12张图片

 16.2.3. 简便形式(只针对默认暴露)

import m3 from "./js/m3.js";
console.log(m3);//{school: '清华大学', change: ƒ}

16.3 模块化方式2

// 下面js代码放在./js/app.js文件中
//入口文件

//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";

console.log(m1);
console.log(m2);
console.log(m3);

 结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第13张图片

 16.4 bael对es6模块化代码转换

Babel 概述:
Babel 是一个 JavaScript 编译器;
Babel 能够将新的ES规范语法转换成ES5的语法;
因为不是所有的浏览器都支持最新的 ES 规范,所以,一般项目中都需要使用 Babel 进行转换;
步骤:使用 Babel 转换 JS 代码 —— 打包成一个文件 —— 使用时引入即可;

步骤

 第一步:安装工具babel-cli(命令行工具) babel-preset-envES转换工具) browserify(打包工具, 项目中使用的是webpack);

第二步:初始化项目

npm init -y
第三步:安装
npm i babel-cli babel-preset-env browserify -D
第四步:使用 babel 转换
npx babel js(js目录)  -d dist/js (转化后的js目录) --presets=babel-preset-env
第五步:打包
npx browserify dist/js/app.js -o dist/bundle.js
第六步:在使用时引入 bundle.js
< script src = "./js/bundle.js" type = "module" >< /script>
转换前后对比:
转换前:
//分别暴露
export let school = '离歌笑';
export function teach(){
    console.log('一曲离歌笑江湖');
}
转换后:
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.teach = teach;
//分别暴露
var school = exports.school = '离歌笑';
function teach() {
    console.log('一曲离歌笑江湖');
}

16.5 ES6模块化引入NPM

第一步:安装jquery

npm i jquery

第二步:在app.js使用jquery

//修改背景颜色为粉色
import $ from 'jquery';//const $ = require("jquery");
$('body').css("background","pink");

 第三步:重新转换和打包

npx babel js(js目录)  -d dist/js (转化后的js目录) --presets=babel-preset-env

npx browserify dist/js/app.js -o dist/bundle.js


二、ES7新特性

1Array.prototype.includes

概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值;
判断数组中是否包含某元素,语法: arr.includes( 元素值 )
const renming = ['李逍遥','赵灵儿','林月如','刘晋元'];
console.log(renming.includes('李逍遥'));//true
console.log(renming.includes('离歌笑'));//false

2、指数操作符

概述:
ES7 中引入指数运算符「 ** 」,用来实现幂运算,功能与 Math.pow 结果相同;
幂运算的简化写法,例如: 2 10 次方: 2**10
//**(指数操作符)
console.log(2**10);//1024
console.log(Math.pow(2,10));//1024

三、ES8的新特性

1async await

概述:
async await 两种语法结合可以让异步代码看起来像同步代码一样;
简化异步函数的写法;

 3.1.1async函数

概述:
1. async 函数的返回值为 promise 对象;
2. promise 对象的结果由 async 函数执行的返回值决定;

1.返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象

2.抛出错误,返回的结果是一个失败的Promise

3.返回的结果如果是一个Promise对象,结果成功就是成功,失败就是失败

// async函数
async function fn(){
    //返回一个字符串
    // return '离歌笑';//fulfilled
    //返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象
    // return; 
    //抛出错误,返回的结果是一个失败的Promise
    // throw new Error('出错啦!');
    //返回的结果如果是一个Promise对象
    return new Promise((resolve,reject)=>{
        resolve('成功的数据');//fulfilled
        //   reject('失败的数据');//rejected
    })
}    
const result = fn();
// console.log(result);
//调用then方法
result.then(value=>{
    console.log(value);
},(reason)=>{
    console.warn(reason);
})

3.1.2await 表达式

概述:
1. await 必须写在 async 函数中;
2. await 右侧的表达式一般为 promise 对象;
3. await 返回的是 promise 成功的值;
4. await promise 失败了 , 就会抛出异常 , 需要通过 try...catch 捕获处理;
//创建Promise对象
const p = new Promise((resolve,reject)=>{
    // resolve('成功啦哦哦');
    reject('失败的原因很复杂');
})    

//await 要放在async函数中
async function main(){
    try{
        const result = await p;
        console.log(result);
    }
    catch(e){
        console.log(e);//失败的原因很复杂
    }
}
//调用函数
main();

 3.1.3async await 读取文件

const fs = require('fs');
function readCao(){
    return new Promise((reslove,reject)=>{
        fs.readFile('./resource/草.txt',(err,data)=>{
            if(err){reject(err);}
            reslove(data);
        })
    })
}
function readWuTi(){
    return new Promise((reslove,reject)=>{
        fs.readFile('./resource/无题.txt',(err,data)=>{
            if(err){reject(err);}
            reslove(data);
        })
    })
}
function readTiYanTa(){
    return new Promise((reslove,reject)=>{
        fs.readFile('./resource/题雁塔.txt',(err,data)=>{
            if(err){reject(err);}
            reslove(data);
        })
    })
}

async function main(){
    //文章1
    try{
        let cao = await readCao();
        console.log(cao.toString());
    }
    catch(e){
        console.log(e);
    }
    //文章2
    try{
        let wuti = await readWuTi();
        console.log(wuti.toString());
    }
    catch(e){
        console.log(e);
    }
    //文章3
    try{
        let tiyanta = await readTiYanTa();
        console.log(tiyanta.toString());
    }
    catch(e){
        console.log(e);
    }
}
main();

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第14张图片


 3.1.4async await 结合发送ajax请求

//发送Ajax请求,返回的结果是Pomise对象
function sendAJAX(url) {
    return new Promise((resolve,reject)=>{
        //1.创建对象
        const xhr = new XMLHttpRequest();
        //2.初始化
        xhr.open('GET',url);
        //3.发送
        xhr.send();
        //4.事件绑定
        xhr.onreadystatechange = ()=>{
            if(xhr.readyState === 4)
            {
                if(xhr.status>=200 && xhr.status<300)
                {
                    //成功
                    resolve(xhr.response);
                }
                else{
                    //失败
                    reject(xhr.status);
                }
            }
        }
    })
}

//Promise then方法测试
// sendAJAX('https://api.apiopen.top/getJoke').then((value)=>{
//     console.log(value);
// },(reason)=>{
//     console.log(reason);
// })

//使用async与await
async function main(){
    //发送AJAX请求
    let result =  await sendAJAX('https://api.apiopen.top/getJoke');
    console.log(result);
}
main();

2、对象方法扩展

Object.valuesObject.entries

Object.getOwnPropertyDescriptors

1. Object.values() 方法:返回一个给定对象的 所有可枚举属性值 的数组;
2. Object.entries() 方法:返回一个给定对象自身可遍历属性 [key,value] 的数组; (对象变数组)
3. Object.getOwnPropertyDescriptors() 该方法:返回指定对象所有自身属性的描述对象;
//声明对象
const school = {
    name:'离歌笑',
    cities:['杭州','长安','汴梁'],
    zhiye:['daxia','taifu','gongzhu']
}    

//获取对象所有的键
console.log(Object.keys(school));//['name', 'cities', 'zhiye']
//获取对象所有的值
console.log(Object.values(school));//['离歌笑', Array(3), Array(3)]0: "离歌笑"1: (3) ['杭州', '长安', '汴梁']2: (3) ['daxia', 'taifu', 'gongzhu']length: 3[[Prototype]]: Array(0)
//entries
console.log(Object.entries(school));//[Array(2), Array(2), Array(2)]
//创建Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));//['杭州', '长安', '汴梁']

//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));//{name: {…}, cities: {…}, zhiye: {…}}

const obj = Object.create(null,{
    name:{
        //设置值
        value:'离歌笑',
        writable:true,//值是否可以重写。true|false 默认为false
        configurable:true,//目标属性是否可以被删除或是否可以再次修改特特性 true|false 默认为false
        enumerable:true,//目标属性是否可以被枚举。true|false 默认为false
    }
})

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第15张图片

五、ES9 新特性

1Rest 参数与 spread 扩展运算符

概述:
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9
为对象提供了 像数组一样的 rest 参数和扩展运算符;
// Rest参数与spread扩展运算符 
// Rest 参数与 spread 扩展运算符在 ES6 中已经引入,
// 不过 ES6 中只针对于数组,在 ES9 中为对象提供了像 
// 数组一样的 rest 参数和扩展运算符    
function connect({name,age,...user}){
    console.log(name);
    console.log(age);
    console.log(user);
}

connect({
    name:'离歌笑',
    age:20,
    price:5000,
    wuli:10000000
})
const skillOne = {
    x:'仙风云体术'
}
const skillTwo = {
    z:'醉仙望月步',
    a:'爱无限'
}
const skillThree = {
    q:'七诀剑气'
}
const skillFour = {
    y:'御剑术'
}

const lixiaoyao = {...skillOne,...skillTwo,...skillThree,...skillFour};//对象的合并
console.log(lixiaoyao);//{x: '仙风云体术', z: '醉仙望月步', q: '七诀剑气', y: '御剑术'}

结果:

ES6(ECMAScript6)-ES11 从入门到修仙_第16张图片



 2、正则扩展:命名捕获分组

概述:
ES9 允许命名捕获组使用符号『 ? , 这样获取捕获结果可读性更强;
//声明一个字符串
let str = '离歌笑';

//提取url 与[标签文本]
const reg = /(.*)<\/a>/

//执行
const result = reg.exec(str);
console.log(result[1]);//http://baidu.com
console.log(result[2]);//离歌笑

let str1 = '离歌笑';
const reg1 = /(?.*)<\/a>/;
const result1 = reg.exec(str1); 
// console.log(result1);
console.log(result1.groups.url);//http://baidu.com
console.log(result1.groups.text);//离歌笑

3、正则扩展:反向断言

概述:
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选;
//声明字符串
let str = 'JS5201314你知道么555啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);

//反向断言
const reg1 = /(?<=么)\d+/;
const result1 = reg1.exec(str);
console.log(result1);

4、正则扩展:dotAll 模式

概述:
正则表达式中点 . 匹配除回车外的任何单字符,标记『 s 』改变这种行为,允许行终止符出现;

//dot . 元字符 除换行符以外的任意单个字符
let str = `
    
`;

//声明正则
// const reg = /
  • \s+(.*?)<\/a>\s+

    (.*?)<\/p/; const reg = /

  • .*?(.*?)<\/a>.*?

    (.*?)<\/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);

  • 结果:

     六、ES10 新特性

    1Object.fromEntries

    概述:
    将二维数组或者 map 转换成对象;
    之前学的 Object.entries 是将对象转换成二维数组;
    // Object.fromEntries:将二维数组或者map转换成对象 
    // 之前学的Object.entries是将对象转换成二维数组 
    // 此方法接收的是一个二维数组,或者是一个map集合 
    // 二维数组
    const result = Object.fromEntries([
    ['name','离歌笑'],
    ['city','长安,余杭,仙灵']
    ]);
    console.log(result);//{name: '离歌笑', city: '长安,余杭,仙灵'}
    //Map
    const m = new Map();
    m.set('name','ligexiao')
    console.log(m);//Map(1) {'name' => 'ligexiao'}
    const result1 = Object.fromEntries(m);
    console.log(result1.name);//ligexiao
    console.log(result1);//{name: 'ligexiao'}
    //Object.entries ES8
    const arr = Object.entries({
    name:'绿儿'
    });
    console.log(arr);

     结果:

    ES6(ECMAScript6)-ES11 从入门到修仙_第17张图片

     2trimStart trimEnd

    概述:
    去掉字符串前后的空白字符;
    //trim
    let str = '   ligexiao   ';
    console.log(str);//   ligexiao   
    console.log(str.trim());//ligexiao
    console.log(str.trimStart());//ligexiao   
    console.log(str.trimEnd());//   ligexiao

     结果:

    3Array.prototype.flat flatMap

    概述:
    将多维数组转换成低维数组;
    //flat 平
    //将多维数组转化为低维数组
    // const arr = [1,2,3,[4,5,6]];// [1, 2, 3, 4, 5, 6]
    // const arr = [1,2,3,4,[5,6,7,[8,9,0]]];// [1, 2, 3, 4, 5, 6, 7, Array(3)]    Array(3):[8, 9, 0]
    const arr = [1,2,3,4,[5,6,7,[8,9,0]]];
    //参数为深度,是一个数字
    console.log(arr.flat(2));// [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    
    //flatMap 将map得出的多维数组转化为低维数组
    const arr1 = [1,2,3,4];
    const result0 = arr1.map(item=>item * 10);//[10, 20, 30, 40]
    const result1 = arr1.map(item=>[item*10]);//Array(1), Array(1), Array(1), Array(1)] -> [10][20][30][40]
    const result2 = arr1.flatMap(item=>item * 10);//[10, 20, 30, 40]
    console.log(result0);
    console.log(result1);
    console.log(result2);

     结果:

    ES6(ECMAScript6)-ES11 从入门到修仙_第18张图片

    4Symbol.prototype.description

    概述:
    获取 Symbol 的描述字符串;
    //创建Symbol
    let s = Symbol('离歌笑');
    console.log(s.description);//离歌笑

    七、ES11 新特性

    1String.prototype.matchAll

    概述:
    用来得到正则批量匹配的结果;
    let str = `
        
    `;
    //声明正则
    const reg = /
  • .*?(.*?)<\/a>.*?

    (.*?)<\/p>/sg //调用方法 const result = str.matchAll(reg); for(let v of result) { console.log(v); } // const arr = [...result]; // console.log(arr);

  •   结果:

    ES6(ECMAScript6)-ES11 从入门到修仙_第19张图片

    2、类的私有属性

    概述:
    私有属性外部不可访问直接; (可以在内部使用,不能在外部使用)
    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','40kg');
    console.log(girl);
    console.log(girl.name);
    console.log(girl.#age);
    console.log(girl.#weight);
    girl.intro();

    3Promise.allSettled

    概述:
    获取多个 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);
    const res = Promise.all([p1,p2]);//两个都为成功才算成功,一个失败则为失败
    console.log(res);

     结果:

    调用allSettled方法

    ES6(ECMAScript6)-ES11 从入门到修仙_第20张图片

    调用all方法

    ES6(ECMAScript6)-ES11 从入门到修仙_第21张图片

    ES6(ECMAScript6)-ES11 从入门到修仙_第22张图片

    4、可选链操作符

    概述:
    ?.
    如果存在则往下走,省略对对象是否传入的层层判断;
    //?.
    function main(config)
    {
        const dbHost = config && config.db && config.db.host;
        console.log(dbHost);//192.168.0.1
        const cacheHost = config?.cache?.host;
        console.log(cacheHost);//192.168.0.2
    }
    main({
        db:{
            host:'192.168.0.1',
            username:'root'
        },
        cache:{
            host:'192.168.0.2',
            username:'admin',
        }
    })

     5、动态 import 导入

     概述:

    动态导入模块,什么时候使用时候导入;

    html页面:

    
    

    app.js:

    //静态import
    import * as m1 from './hello.js';
    const btn = document.getElementById('btn');
    btn.onclick = function(){
        // m1.hello2();
        //动态import
        import('./hello.js').then(module=>{
            module.hello();
        })
    }

    hello.js:

    export function hello(){
        alert('贝贝 晶晶 欢欢 迎迎 妮妮');
    }
    export function hello2(){
        alert('贝贝 晶晶 欢欢 迎迎 妮妮2');
    }

    6BigInt

    概述:
    更大的整数;
    //大整形
    let n = 521n;
    console.log(n,typeof(n));//521n 'bigint'
    
    //函数:普通整形转大整形
    let x = 123;
    console.log(BigInt(n));//521n
    // console.log(BigInt(1.2)); //出错了,BigInt不能用浮点数计算
    
    //用于更大数值的运算
    let max = Number.MAX_SAFE_INTEGER;
    console.log(max);//9007199254740991
    console.log(max+1);//9007199254740992
    console.log(max+2);//9007199254740992 出错了max+1为最大计算
    
    console.log(BigInt(max));//9007199254740991n
    console.log(BigInt(max)+BigInt(1));//9007199254740992n
    console.log(BigInt(max)+BigInt(2));//9007199254740993n

     结果: 

    ES6(ECMAScript6)-ES11 从入门到修仙_第23张图片

     7globalThis 对象

    概述:
    始终指向全局对象 window
    console.log(globalThis);

     结果:

    ES6(ECMAScript6)-ES11 从入门到修仙_第24张图片

    你可能感兴趣的:(JS,javascript,前端,vue.js)