ES6-11 Note

1、let 关键字

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

1. 不允许重复声明;

2. 块儿级作用域(局部变量);

3. 不存在变量提升;

4. 不影响作用域链;

 应用场景:

          以后声明变量使用 let 就对了;

<script>
        // 获取div元素对象
        let items = document.getElementsByClassName('item');
        // 遍历并绑定事件
        for (let i = 0; i < items.length; i++) {
            items[i].onclick = function () {
                // 修改当前元素的背景颜色
                // this.style.background = 'pink'; // 写法一:常规写法一般无异常
                items[i].style.background = 'pink'; // 写法二
                // 写法二:需要注意的是for循环内的i必须使用let声明
                // 如果使用var就会报错,因为var是全局变量,
                // 经过循环之后i的值会变成3,items[i]就会下标越界
                // let是局部变量
                // 我们要明白的是当我们点击的时候,这个i是哪个值
                // 使用var相当于是:
                // { var i = 0; }
                // { var i = 1; }
                // { var i = 2; }
                // { var i = 3; }
                // 下面的声明会将上面的覆盖掉,所以点击事件每次找到的都是3
                // 而使用let相当于是:
                // { let i = 0; }
                // { let i = 1; }
                // { let i = 2; }
                // { let i = 3; }
                // 由于let声明的是局部变量,每一个保持着原来的值
                // 点击事件调用的时候拿到的是对应的i
            }
        }
    </script>

外层for循环只是给每个item绑定了点击事件,然后点击事件是异步任务,for已经执行完了.

这里先循环把每个div添加上了事件,循环结束后i已经变成3了.

click是异步任务,执行时i的值是已经循环完的值了.

 

2const 关键字

特性:
const 关键字用来声明 常量 const 声明有以下特点:
1. 声明必须赋初始值;
2. 标识符一般为大写(习惯);
3. 不允许重复声明;
4. 值不允许修改;
5. 块儿级作用域(局部变量);

 保存的地址,地址没有变化。

3、变量和对象的解构赋值

什么是解构赋值:
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为 解构赋值
解构同名属性就是获取那个同名属性,自定义变量名就按顺序解构赋值。
应用场景:
频繁使用对象方法、数组元素,就可以使用解构赋值形式;

 

 4、模板字符串

概述: 模板字符串(template string)是增强版的字符串,用反引号(`)标识,

特点: 字符串中可以出现换行符; 可以使用 ${xxx} 形式引用变量;

// 定义字符串
let str = `<ul>

 <li>沈腾</li>
 <li>玛丽</li>
 <li>魏翔</li>
 <li>艾伦</li>
 </ul>`;
// 变量拼接
let star = '王宁';
let result = `${star}在前几年离开了开心麻花`;

5、简化对象和函数写法

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

let name = '尚硅谷';
let slogon = '永远追求行业更高标准';
let improve = function () {
 console.log('可以提高你的技能');
}
//属性和方法简写
let atguigu = {
 name,
 slogon,
 improve,
 change() {
 console.log('可以改变你')
 }
};

6、箭头函数

概述:

ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿 名函数的定义;

箭头函数的注意点:

1. 如果形参只有一个,则小括号可以省略;

2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果;

3. 箭头函数 this 指向声明时所在作用域下 this 的值;

4. 箭头函数不能作为构造函数实例化;

5. 不能使用 arguments;

特性:

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

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

3. 不能使用 arguments 变量;

箭头函数的this会继承父执行上下文里面的this

注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适;

 <script>
        // ES6 允许使用「箭头」(=>)定义函数。
        //声明一个函数
        // let fn = function(){

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


        //1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
        function getName(){
            console.log(this.name);
        }
        let getName2 = () => {
            console.log(this.name);
        }

        //设置 window 对象的 name 属性
        window.name = '尚硅谷';
        const school = {
            name: "ATGUIGU"
        }

        //直接调用
        // getName();
        // getName2();

        //call 方法调用
        // getName.call(school);
        // getName2.call(school);

        //2. 不能作为构造实例化对象
        // let Person = (name, age) => {
        //     this.name = name;
        //     this.age = age;
        // }
        // let me = new Person('xiao',30);
        // console.log(me);

        //3. 不能使用 arguments 变量
        // let fn = () => {
        //     console.log(arguments);
        // }
        // fn(1,2,3);

        //4. 箭头函数的简写
            //1) 省略小括号, 当形参有且只有一个的时候
            // let add = n => {
            //     return n + n;
            // }
            // console.log(add(9));
            //2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
            // 而且语句的执行结果就是函数的返回值
            let pow = n => n * n;
                
            console.log(pow(8));

    </script>

需求-1:点击 div 2s 后颜色变成『粉色』:

JavaScript 内置函数的回调函数 this 一般都指向 window,箭头函数因为没有自己的this,找到外部的普通函数的 this ,也就是 ad (普通函数被 ad 调用)

 //需求-1  点击 div 2s 后颜色变成『粉色』
        //获取元素
        let ad = document.getElementById('ad');
        //绑定事件
        ad.addEventListener("click", function(){
            //保存 this 的值
            //_this 表示外部调用监听事件的元素本身,而setTimeout方法内部的this仍然是指向window
            ///JavaScript 内置函数的回调函数 this 一般都指向 window,箭头函数因为没有自己的this,
            //找到外部的普通函数的 this ,也就是 ad (普通函数被 ad 调用)
            // let _this = this;
            //定时器
            setTimeout(() => {
                //修改背景颜色 this
                // console.log(this);
                // _this.style.background = 'pink';
                this.style.background = 'pink';
            }, 2000);
        });

需求-2 从数组中返回偶数的元素:

 //需求-2  从数组中返回偶数的元素
        const arr = [1,6,9,10,100,25];

        //filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表,
        //接收两个参数,一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断

        //filter() 函数用于过滤序列序列的每个元素作为参数传递给函数进行判断,
        //然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

        
        // const result = arr.filter(function(item){
        //     if(item % 2 === 0){
        //         return true;
        //     }else{
        //         return false;
        //     }
        // });
        
        const result = arr.filter(item => item % 2 === 0);

        console.log(result);

        // 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
        // 箭头函数不适合与 this 有关的回调.  事件回调,(绑定的事件的回调,不再指向事件源,而是外层执行上下文的this) 对象的方法
let a = {
        b:{
            c:function(){
                console.log(this);
            },
            e:()=>{
                console.log(this);
            }
        },
        d:function(){
            console.log(this);
        }
    }

    a.b.c(); //c
    //在函数作为对象的属性情况下,function函数和箭头函数中的this指向不相同。箭头函数中的this并没有指向调用该函数的对象,而是指向window。
    a.b.e(); //window
    a.d(); //a
            

7、ES6中函数参数的默认值

概述: ES允许给函数的参数赋初始值;

 <script>
        //ES6 允许给函数参数赋值初始值
        //1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
        // function add(a,c=10,b) {
        //     return a + b + c;
        // }
        // let result = add(1,2);
        // console.log(result);

        //2. 与解构赋值结合
        //host默认值,没有传入host参数,则用默认值
        function connect({host="127.0.0.1", username,password, port}){
            console.log(host)
            console.log(username)
            console.log(password)
            console.log(port)
        }
        connect({
            host: 'atguigu.com',
            username: 'root',
            password: 'root',
            port: 3306
        })
    </script>

8、rest参数

概述: ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;

<script>
        //ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
        //ES5 获取实参的方式
        function date(){
            console.log(arguments);//是一个对象
        }
        date('白芷','阿娇','思慧');

        ///rest 参数
        function datee(...args){
            console.log(args);//是一个数组 可以使用数组的方法 filter some every map 
        }
        datee('阿娇','柏芝','思慧');

        //rest 参数必须要放到参数最后
        function fn(a,b,...args){
            console.log(a);//1
            console.log(b);//2
            console.log(args);//3,4,5,6
        }
        fn(1,2,3,4,5,6);

    </script>

9、扩展运算符

介绍:

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

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

扩展运算符(spread)也是三个点(...)。

它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参 数序列,对数组进行解包;

 <script>
        // 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
        //声明一个数组 ...
        const tfboys = ['易烊千玺','王源','王俊凯'];
        // => '易烊千玺','王源','王俊凯'

        // 声明一个函数
        function chunwan(){
            console.log(arguments);
        }

        chunwan(tfboys)
        chunwan(...tfboys);//相当于 chunwan('易烊千玺','王源','王俊凯')

        

    </script>

应用:

 <div></div>
    <div></div>
    <div></div>
    <script>
        //1. 数组的合并 情圣  误杀  唐探
        const kuaizi = ['王太利','肖央'];
        const fenghuang = ['曾毅','玲花'];
        const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
        //扩展运算符可以把数组转为逗号分割的参数序列
        const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
        console.log(zuixuanxiaopingguo);

        //2. 数组的克隆
        const sanzhihua = ['E','G','M'];
        //浅拷贝:就是拷贝变量所存的值,如果是引用变量,那拷贝的就是它里面的地址
        const sanyecao = [...sanzhihua];//  ['E','G','M']
        console.log(sanyecao);

        //3. 将伪数组转为真正的数组
        const divs = document.querySelectorAll('div');
        const divArr = [...divs];
        console.log(divArr);// arguments
        
        
    </script>

divs是一个对象

 divArr

 10、Symbol 

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

特点:

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

2. Symbol 值不能与其他数据进行运算;

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

 <script>

        //创建Symbol
        //Symbol作为一个函数
        let s = Symbol();
        // console.log(s, typeof s);
        let s2 = Symbol('尚硅谷');
        let s3 = Symbol('尚硅谷');


        //Symbol.for 创建
        //Symbol作为一个对象
        let s4 = Symbol.for('尚硅谷');
        let s5 = Symbol.for('尚硅谷');


        //不能与其他数据进行运算
        //    let result = s + 100;
        //    let result = s > 100;
        //    let result = s + s;

        // USONB 
        // you are so niubility 
        // u  undefined
        // s  string  symbol
        // o  object
        // n  null number
        // b  boolean

    </script>

Symbol创建对象属性:

<script>
        //向对象中添加方法 up down
        let game = {
            name:'俄罗斯方块',
            up: function(){},
            down: function(){}
        };
        
        
        //声明一个对象
        let methods = {
            up: Symbol(),
            down: Symbol()
        };

        game[methods.up] = function(){
            console.log("我可以改变形状");
        }

        game[methods.down] = function(){
            console.log("我可以快速下降!!");
        }

        console.log(game);

        
        let youxi = {
            name:"狼人杀",
            [Symbol('say')]: function(){
                console.log("我可以发言")
            },
            [Symbol('zibao')]: function(){
                console.log('我可以自爆');
            }
        }

        console.log(youxi)

        
    </script>

 Symbol内置值:

概述:

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方 法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;

方法:

<script>
        class Person{
            static [Symbol.hasInstance](param){
                console.log(param);//o
                console.log("我被用来检测类型了");
                //return false;
            }
        }

        let o = {};

        console.log(o instanceof Person);//false

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

11、迭代器

for...in 返回的是字符串。

for...of 

概述:

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

特性:

ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费;

原生具备 iterator 接口的数据(可用 for of 遍历):

Array; Arguments; Set; Map; String; TypedArray; NodeList;

工作原理:

1. 创建一个指针对象,指向当前数据结构的起始位置;

2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;

3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;

4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;

注:需要自定义遍历数据的时候,要想到迭代器;

<script>
        //声明一个数组
        const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];

        ///使用 for...of 遍历数组
        for(let v of xiyou){
            console.log(v);
        }

        console.log(xiyou)

        let iterator = xiyou[Symbol.iterator]();

        //调用对象的next方法
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
    </script>

迭代器自定义遍历对象:

<script>
        //声明一个对象
        const banji = {
            name: "终极一班",
            stus: [
                'xiaoming',
                'xiaoning',
                'xiaotian',
                'knight'
            ],
            [Symbol.iterator]() {
                //索引变量
                let index = 0;
                //
                let _this = this;
                return {
                    next: function () {
                        if (index < _this.stus.length) {
                            const result = { value: _this.stus[index], done: false };
                            //下标自增
                            index++;
                            //返回结果
                            return result;
                        }else{
                            return {value: undefined, done: true};
                        }
                    }
                };
            }
        }

        //遍历这个对象 
        for (let v of banji) {
            console.log(v);
        }
    </script>

12、生成器

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

 <script>    
        //生成器其实就是一个特殊的函数
        //异步编程  纯回调函数  node fs  ajax mongodb
        //函数代码的分隔符
        function * gen(){
            // console.log(111);
            yield '一只没有耳朵';
            // console.log(222);
            yield '一只没有尾部';
            // console.log(333);
            yield '真奇怪';
            // console.log(444);
        }

        let iterator = gen();
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());

        //遍历
        // for(let v of gen()){
        //     console.log(v);
        // }

    </script>

 

生成器函数的参数传递: 

<script>
        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());
        //next方法可以传入实参
        //参数作为传入的参数作为第一条(上一条)语句yield 111的返回结果
        console.log(iterator.next('BBB'));
        console.log(iterator.next('CCC'));
        console.log(iterator.next('DDD'));
        
    </script>

生成器函数实例1:

<script>
        // 异步编程  文件操作 网络操作(ajax, request) 数据库操作
        // 1s 后控制台输出 111  2s后输出 222  3s后输出 333 
        // 回调地狱
        // setTimeout(() => {
        //     console.log(111);
        //     setTimeout(() => {
        //         console.log(222);
        //         setTimeout(() => {
        //             console.log(333);
        //         }, 3000);
        //     }, 2000);
        // }, 1000);

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

    </script>

生成器函数实例2:

<script>
        //模拟获取  用户数据  订单数据  商品数据 
        function getUsers(){
            setTimeout(()=>{
                let data = '用户数据';
                //调用 next 方法, 并且将数据传入
                 //next方法可以传入实参
                 //参数作为传入的参数作为第一条(上一条)语句yield  getUsers()的返回结果
                 //第二次调用next
                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();
            let goods = yield getGoods();
        }

        //调用生成器函数
        let iterator = gen();
        iterator.next();

        

    </script>

13、Promise

概述:

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

1. Promise 构造函数: Promise (excutor) {};

2. Promise.prototype.then 方法;

3. Promise.prototype.catch 方法;

<script>
        //实例化 Promise 对象
        //接收一个函数作为参数
        const p = new Promise(function(resolve, reject){
            setTimeout(function(){
                //
                // let data = '数据库中的用户数据';
                // resolve p对象状态变为成功 
                //调用then方法的第一 个回调函数
                // resolve(data);

                //p对象状态变为成功
                //调用then方法的第二个回调函数
                let err = '数据读取失败';
                reject(err);
            }, 1000);
        });

        //调用 promise 对象的 then 方法
        //接收两个函数作为参数
        //value 成功 
        //reason 失败吧 
        p.then(function(value){
            console.log(value);
        }, function(reason){
            console.error(reason);
        })
    </script>

Promise封装读取文件:

//1. 引入 fs 模块
const fs = require('fs');

//2. 调用方法读取文件
//第一个参数为文件地址,第二个 参数为回调函数
fs.readFile('./resources/为学.md', (err, data)=>{
    //如果失败, 则抛出错误
    if(err) throw err;
    //如果没有出错, 则输出内容
    console.log(data.toString());
});

//3. 使用 Promise 封装
const p = new Promise(function(resolve, reject){
    fs.readFile("./resources/为学.mda", (err, data)=>{
        //判断如果失败
        if(err) reject(err);
        //如果成功
        //resolve函数修改p状态为成功
        //参数设置成功的值
        resolve(data);
    });
});

p.then(function(value){
    //value是一个bufferr
    console.log(value.toString());
}, function(reason){
    console.log("读取失败!!");
});

原始Ajax请求

<script>
        // 请求地址:https://api.apiopen.top/getJoke
        // 原生请求
        // 1、创建对象
        const xhr = new XMLHttpRequest();
        // 2、初始化
        xhr.open("GET", "https://api.apiopen.top/getJoke");
        // 3、发送
        xhr.send();
        // 4、绑定事件,处理响应结果
        xhr.onreadystatechange = function () {
            // 判断状态
            if (xhr.readyState == 4) {
                // 判断响应状态码 200-299
                if (xhr.status >= 200 && xhr.status <= 299) {
                    // 成功
                    console.log(xhr.response);
                } else {
                    // 失败
                    console.error(xhr.status);
                }
            }
        }
    </script>

Promise封装Ajax请求:

 <script>
        // 接口地址: https://api.apiopen.top/getJoke
        const p = new Promise((resolve, reject) => {
            //1. 创建对象
            const xhr = new XMLHttpRequest();

            //2. 初始化
            xhr.open("GET", "https://api.apiopen.top/getJoke");

            //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(function (value) {
            console.log(value);
        }, function (reason) {
            console.error(reason);
        });
    </script>

Promise.prototype.then:

then 方法的返回值也是一个Promise对象

对象状态由回调函数的执行结果决定。

 //1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值 

 不写return则 undefined为成功值

 return一个promise

抛出错误

<script>
        //创建 promise 对象
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('用户数据');
                // reject('出错啦');
            }, 1000)
        });

        //调用 then 方法  then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
        //1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值

        // const result = p.then(value => {
        //     console.log(value);
        //     //1. 非 promise 类型的属性
        //     // return 'iloveyou';
        //     //2. 是 promise 对象
        //     // return new Promise((resolve, reject)=>{
        //     //     // resolve('ok');
        //     //     reject('error');
        //     // });
        //     //3. 抛出错误
        //     // throw new Error('出错啦!');
        //     throw '出错啦!';
        // }, reason=>{
        //     console.warn(reason);
        // });

        //链式调用
        //是从前往后,一个调用成功后return出下一个promise对象,以此类推
        p.then(value=>{

        }).then(value=>{

        });


    </script>

Promise实践练习:

“回调地狱”方式写法:

//引入 fs 模块
const fs = require("fs");

fs.readFile('./resources/为学.md', (err, data1)=>{
    fs.readFile('./resources/插秧诗.md', (err, data2)=>{
        fs.readFile('./resources/观书有感.md', (err, data3)=>{
            let result = data1 + '\r\n' +data2  +'\r\n'+ data3;
            console.log(result);
        });
    });
});

Promise实现:


//使用 promise 实现
const p = new Promise((resolve, reject) => {
    fs.readFile("./resources/为学.md", (err, data) => {
        //如果成功
        //resolve函数修改p状态为成功
        //参数设置成功的值,是该文件内容
        resolve(data);
    });
});
//value是第一个文件内容
p.then(value => {
    //返回一个promise对象
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/插秧诗.md", (err, data) => {
            //此次成功p.then返回的promise也是成功的,此次成功的值就是p.then返回的promise成功的值
            resolve([value, data]);
        });
    });

    //此次的value就是[value, data]
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/观书有感.md", (err, data) => {
            //压入
            value.push(data);
            //此次成功.then返回的promise也是成功的,此次成功的值就是.then返回的promise成功的值
            resolve(value);
        });
    })
    //value就是三个文件的内容
}).then(value => {
    console.log(value.join('\r\n'));
});

Promise对象catch方法:

<script>
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                //设置 p 对象的状态为失败, 并设置失败的值为"出错啦!"
                reject("出错啦!");
            }, 1000)
        });

        // p.then(function(value){}, function(reason){
        //     console.error(reason);
        // });

        p.catch(function(reason){
            console.warn(reason);
        });
    </script>

14、Set集合

概述: ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法: 1. size 返回集合的元素个数;

2. add 增加一个新元素,返回当前集合;

3. delete 删除元素,返回 boolean 值;

4. has 检测集合中是否包含某个元素,返回 boolean 值;

5. clear 清空集合,返回 undefined;

 <script>
        //声明一个 set
        let s = new Set();
        let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);

        //元素个数
        console.log(s2.size);
        //添加新的元素
        s2.add('喜事儿');
        //删除元素
        s2.delete('坏事儿');
        //检测
        console.log(s2.has('糟心事'));
        //清空
        s2.clear();
        console.log(s2);

        for(let v of s2){
            console.log(v);
        }
        
    </script>

Set集合实践:

<script>
        let arr = [1,2,3,4,5,4,3,2,1];
        //1. 数组去重
        //扩展运算符
        let result = [...new Set(arr)];
        console.log(result);

        //2. 交集
        let arr2 = [4,5,6,5,6];
        //filter创建一个新数组,符合条件的都放进去
        //filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
        //filter()接收的回调函数,其实可以有多个参数。
        //通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:
        let result = [...new Set(arr)].filter(item => {
            let s2 = new Set(arr2);// 4 5 6
            if(s2.has(item)){
                return true;
            }else{
                return false;
            }
        });

        //let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
        console.log(result);


        //3. 并集
        //[...arr, ...arr2]合并数组
        //放入集合去重
        let union = [...new Set([...arr, ...arr2])];
        console.log(union);


        //4. 差集
        let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
        console.log(diff);

    </script>

15、Map集合

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

Map 的属性和方法:

1. size 返回 Map 的元素个数;

2. set 增加一个新元素,返回当前 Map;

3. get 返回键名对象的键值;

4. has 检测 Map 中是否包含某个元素,返回 boolean 值;

5. clear 清空集合,返回 undefined;

<script>
        //声明 Map
        let m = new Map();

        //添加元素
        m.set('name','尚硅谷');
        m.set('change', function(){
            console.log("我们可以改变你!!");
        });
        let key = {
            school : 'ATGUIGU'
        };
        m.set(key, ['北京','上海','深圳']);

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

        //删除
        m.delete('name');

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

        //清空
        m.clear();

        //遍历
        for(let v of m){
            console.log(v);
        }

        // console.log(m);

    </script>

16、class类

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

知识点:

1. class 声明类;

2. constructor 定义构造函数初始化;

3. extends 继承父类;

4. super 调用父级构造方法;

5. static 定义静态方法和属性;

6. 父类方法可以重写;

<script>
        //手机
        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);

        //class
        class Shouji{
            //构造方法 名字不能修改
            constructor(brand, price){
                this.brand = brand;
                this.price = price;
            }

            //添加方法
            //方法必须使用该语法, 不能使用 ES5 的对象完整形式
            call(){
                console.log("我可以打电话!!");
            }
        }

        let onePlus = new Shouji("1+", 1999);

        console.log(onePlus);
    </script>

class静态成员:

name既不在实例对象上也不在原型上,故报错。 

<script>
        function Phone(){

        }
        Phone.name = '手机';
        Phone.change = function(){
            console.log("我可以改变世界");
        }
        Phone.prototype.size = '5.5inch';

        let nokia = new Phone();

        //name既不在实例对象上也不在原型上,故报错
        console.log(nokia.name);
        // nokia.change();
        console.log(nokia.size);



        class Phone{
            //静态属性
            static name = '手机';
            static change(){
                console.log("我可以改变世界");
            }
        }

        let nokia = new Phone();
        console.log(nokia.name);
        console.log(Phone.name);
    </script>

ES5构造函数实现继承:

 <script>
        // ES5构造函数继承
        // 手机
        function Phone(brand, price) {
            this.brand = brand;
            this.price = price;
        }
        Phone.prototype.call = function () {
            console.log("我可以打电话!");
        }
        // 智能手机
        function SmartPhone(brand, price, color, size) {
             //借用Phone函数,给this执行,this是new出来的s
            Phone.call(this, brand, price);
            this.color = color;
            this.size = size;
        }
        // 设置子级构造函数的原型
        SmartPhone.prototype = new Phone;
        SmartPhone.prototype.constructor = SmartPhone;
        // 声明子类的方法
        SmartPhone.prototype.photo = function () {
            console.log("我可以拍照!");
        }
        SmartPhone.prototype.game = function () {
            console.log("我可以玩游戏!");
        }
        const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
        console.log(chuizi);
        chuizi.call();
        chuizi.photo();
        chuizi.game();
    </script>v

ES6class类继承:

<script>
        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('我可以进行视频通话');
            }
        }

        const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
        // console.log(xiaomi);
        xiaomi.call();
        xiaomi.photo();
        xiaomi.playGame();
    </script>

子类对父类方法重写:

 //调用子类重写的方法
        xiaomi.call();
        //调用父类的方法
        xiaomi.__proto__.__proto__.call()

 class中的getter和setter设置:

 <script>
        // get 和 set  
        class Phone{
            

            get price(){
                console.log("价格属性被读取了");
                return '123';
            }

            set price(newVal){
                
                console.log('价格属性被修改了');
                console.log(newVal)
            }
        }

        //实例化对象
        let s = new Phone();

        console.log(s.price);
        s.price = 'free';
        console.log(s.price);
    </script>

 17、数值扩展

Number.EPSILON:

Number.EPSILON 是 JavaScript 表示的最小精度;

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;

二进制和八进制:

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;

Number.isFinite() 与 Number.isNaN() :

Number.isFinite() 用来检查一个数值是否为有限的;

Number.isNaN() 用来检查一个值是否为 NaN;

Number.parseInt() 与 Number.parseFloat():

ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;

Math.trunc:

用于去除一个数的小数部分,返回整数部分;

Number.isInteger:

Number.isInteger() 用来判断一个数值是否为整数;

<script>
        //0. Number.EPSILON 是 JavaScript 表示的最小精度
        //EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
        function equal(a, b){
            if(Math.abs(a-b) < Number.EPSILON){
                return true;
            }else{
                return false;
            }
        }
         console.log(0.1 + 0.2);//0.30000000000000004
        console.log(0.1 + 0.2 === 0.3);//false
        console.log(equal(0.1 + 0.2, 0.3))//true

        //1. 二进制和八进制
        let b = 0b1010;//二进制
        let o = 0o777;//八进制
        let d = 100;//十进制
        let x = 0xff;//十六进制
        console.log(x);

        //2. Number.isFinite  检测一个数值是否为有限数
        console.log(Number.isFinite(100));//true
        console.log(Number.isFinite(100/0));//false
        console.log(Number.isFinite(Infinity));//false
        
        //3. Number.isNaN 检测一个数值是否为 NaN 
        console.log(Number.isNaN(123)); //false

        //4. Number.parseInt Number.parseFloat字符串转整数
        console.log(Number.parseInt('5211314love'));//5211314
        console.log(Number.parseFloat('3.1415926神奇'));//3.1415926

        //5. Number.isInteger 判断一个数是否为整数
        console.log(Number.isInteger(5));//true
        console.log(Number.isInteger(2.5));//false

        //6. Math.trunc 将数字的小数部分抹掉  
        console.log(Math.trunc(3.5));///3

        //7. Math.sign 判断一个数到底为正数 负数 还是零
        console.log(Math.sign(100));//1
        console.log(Math.sign(0));//0
        console.log(Math.sign(-20000));//-1

    </script>

 18、对象扩展

概述: ES6 新增了一些 Object 对象的方法:

1. Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);

2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;

3. proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;

<script>
        //1. Object.is 判断两个值是否完全相等 
        console.log(Object.is(120, 120));//  true
        console.log(Object.is(NaN, NaN));//  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://atguigu.com',
            port: 33060,
            name: 'atguigu.com',
            pass: 'iloveyou',
            test2: 'test2'
        }
        //属性重名,后面的属性值覆盖前面的属性值
        console.log(Object.assign(config1, config2));

        //3. Object.setPrototypeOf 设置原型对象  Object.getPrototypeof
        //Object实例对象
        const school = {
            name: '尚硅谷'
        }
        const cities = {
            xiaoqu: ['北京','上海','深圳']
        }

        Object.setPrototypeOf(school, cities);
        console.log(Object.getPrototypeOf(school));//cities
        console.log(school);//school.__proto__===cities


        
    </script>

 19、模块化

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

模块化的好处:

模块化的优势有以下几点: 1. 防止命名冲突; 2. 代码复用; 3. 高维护性;

模块化规范产品:

ES6 之前的模块化规范有:

         1. CommonJS => NodeJS、Browserify; 2. AMD => requireJS; 3. CMD => seaJS;

ES6 模块化语法:

         模块功能主要由两个命令构成:

        export 和 import; export 命令用于规定模块的对外接口(导出模块); import 命令用于输入其他模块提供的功能(导入模块);

简单使用:

 ES6暴露数据语法汇总:

m.js(逐个导出模块):

n.js(统一导出模块): 

o.js(默认导出模块):

 <script type="module" >
        //导入m.js
        import * as m from "./m.js";

        import * as n from "./n.js";

        import * as o from "./o.js";

        console.log(m)
        console.log(n)
        console.log(o)
        o.default.change()


    </script>

ES6导入模块语法汇总:

<script type="module" >
        //1. 通用方式
        //导入m.js
        import * as m from "./m.js";

        import * as n from "./n.js";

        import * as o from "./o.js";

        console.log(m)
        console.log(n)
        console.log(o)
        o.default.change()

        //2.结构赋值
        import{school,show}  from "./m.js";
        console.log(school,show);

        import{school as atguigu,findJob}  from "./n.js";
        console.log(atguigu,findJob);

        import{default as g}  from "./o.js";
        console.log(g);

        //3.简便形式,针对默认暴露
        import m3 from "./o.js";
        console.log(m3)


    </script>

使用模块化的另一种方式:

<script src="./app.js" type="module"></script>

20、Babel对ES6模块化代码转换

Babel概述:

Babel 是一个 JavaScript 编译器;

Babel 能够将新的ES规范语法转换成ES5的语法;

因为不是所有的浏览器都支持最新的ES规范,所以,一般项目中都需要使用Babel进行转换;

步骤:使用Babel转换JS代码——打包成一个文件——使用时引入即可;

三、ES7 新特性

0、功能概述

1、Array.prototype.includes

        判断数组中是否包含某元素,语法:arr.includes(元素值);

2、指数操作符

         幂运算的简化写法,例如:2的10次方:2**10;

1、Array.prototype.includes

概述:

Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值; 判断数组中是否包含某元素,语法:arr.includes(元素值);

<script>
        // includes   indexOf
        const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];

        //判断
        console.log(mingzhu.includes('西游记'));
        console.log(mingzhu.includes('金瓶梅'));

        // **
        console.log(2 ** 10);// 
        console.log(Math.pow(2, 10));
        
    </script>

四、ES8 新特性

0、功能概述

1、async 和 await

        简化异步函数的写法;

2、对象方法扩展

        对象方法扩展;

1、async 和 await 概述:

async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;

简化异步函数的写法;

async 函数:

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

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

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

            //返回的结果如果是一个 Promise 对象

<script>
        //async 函数
        async function fn(){
            // 返回一个字符串
            // return '尚硅谷';

            // 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
            // return;

            //抛出错误, 返回的结果是一个失败的 Promise
            // throw new Error('出错啦!');
            
            //返回的结果如果是一个 Promise 对象
            return new Promise((resolve, reject)=>{
                resolve('成功的数据');
                // reject("失败的错误");
            });
        }

        const result = fn();

        //调用 then 方法
        result.then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        })
    </script>

await 表达式:

概述:

1. await 必须写在 async 函数中;

2. await 右侧的表达式一般为 promise 对象;

3. await 返回的是 promise 成功的值;

4. await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理;

<script>
        //创建 promise 对象
        const p = new Promise((resolve, reject) => {
            // resolve("用户数据");
            reject("失败啦!");
        })

        // await 需要放在 async 函数中.
        async function main() {
            try {
                //await p;返回promise对象成功的值
                let result = await p;
                //
                console.log(result);
            } catch (e) {
                console.log(e);
            }
        }
        //调用函数
        main();
    </script>

async 和 await 读取文件案例:

//1. 引入 fs 模块
const fs = require("fs");

//读取『为学』
//返回结果为一个promise对象
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 函数
//1. async 函数的返回值为 promise 对象;
//2. promise 对象的结果由 async 函数执行的返回值决定;
async function main(){
    //获取为学内容
    //await readWeiXue();返回的是promise成功的值
    let weixue = await readWeiXue();
    //获取插秧诗内容
    let chayang = await readChaYangShi();
    // 获取观书有感
    let guanshu = await readGuanShu();

    console.log(weixue.toString());
    console.log(chayang.toString());
    console.log(guanshu.toString());
}

async 和 await 结合发送ajax请求:

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

        main();
        
    </script>

2、对象方法扩展

Object.values、Object.entries和 Object.getOwnPropertyDescriptors:

1. Object.values()方法:返回一个给定对象的所有可枚举属性值的数组;

2. Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组;

 3. Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;

 <script>
        //声明对象
        const school = {
            name:"尚硅谷",
            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: '尚硅谷',
                //属性特性
                writable: true,
                configurable: true,
                enumerable: true
            } 
        });
    </script>

五、ES9 新特性

0、功能概述

1、Rest 参数与 spread 扩展运算符

概述: Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了 像数组一样的 rest 参数和扩展运算符;

在对象中使Rest参数与spread扩展运算符;

 <!-- 
        Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
        在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
     -->
    <script>
        //rest 参数
        //解构赋值
        function connect({host, port, ...user}){
            console.log(host);
            console.log(port);
            //一个object对象
            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: '猛龙摆尾',
            d:'flash'

        }

        //对象的合并
        const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};

        console.log(mangseng)

      

    </script>

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

简化和增强正则匹配;

概述: ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强;

 <script>
        //声明一个字符串
        let str = '<a href="http://www.atguigu.com">尚硅谷</a>';

        // //提取 url 与 『标签文本』
        const reg = /<a href="(.*)">(.*)<\/a>/;

        // //执行
        const result = reg.exec(str);

        //一个数组
        console.log(result);
        console.log(result[1]);
        console.log(result[2]);

        
        let strr = '<a href="http://www.atguigu.com">尚硅谷</a>';
        //分组命名
        const regx = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;

        const resultt = regx.exec(strr);

        //拥有groups属性
        console.log(resultt)

        console.log(resultt.groups.url);

        console.log(resultt.groups.text);
 </script>

 3、正则扩展:反向断言

概述: ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选;

<script>
        //声明字符串
        let str = 'JS5211314你知道么555啦啦啦';
        //正向断言
        //提取数字555
        const reg = /\d+(?=啦)/;
        const result = reg.exec(str);
        console.log(result);

        //反向断言
        //判断数字前面是不是‘么’
        const regx = /(?<=么)\d+/;
        const resultt = regx.exec(str);
        console.log(resultt);
    </script>

 4、正则扩展:dotAll 模式

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

<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>

六、ES10 新特性

0、功能概述

1、Object.fromEntries 将二维数组或者map转换成对象;

2、trimStart 和 trimEnd 去除字符串前后的空白字符;

3、Array.prototype.flat 与 flatMap 将多维数组降维;

4、Symbol.prototype.description 获取Symbol的字符串描述; 

1、Object.fromEntries

概述:将二维数组或者map转换成对象; 之前学的Object.entries是将对象转换成二维数组;

<script>
        //参数接收二维数组
        const result = Object.fromEntries([
            ['name','尚硅谷'],
            ['xueke', 'Java,大数据,前端,云计算']
        ]);
        //返回一个对象
        console.log(result)

        //传入一个Map作为参数
        //返回一个对象
        const m = new Map();
        m.set('name','ATGUIGU');
        const resultt = Object.fromEntries(m);
        console.log(resultt)


        //Object.entries ES8
        //将一个对象转换为一个二维数组
        const arr = Object.entries({
            name: "尚硅谷"
        })
        console.log(arr);
    </script>

2、trimStart 和 trimEnd

<script>    
        // trim
        let str = '   iloveyou   ';

        console.log(str);
        //清除左侧空白
        console.log(str.trimStart());
        //清除右侧空白
        console.log(str.trimEnd());
    </script>

3、Array.prototype.flat 与 flatMap

概述: 将多维数组转换成低维数组;

<script>
        //flat 平
        //将多维数组转化为低位数组
        const arr = [1,2,3,4,[5,6]];
        const arr1 = [1,2,3,4,[5,6,[7,8,9]]];
        //参数为深度 是一个数字,需要降低多少维
        console.log(arr.flat());  
        console.log(arr1.flat(2));  

        //flatMap
        const arr2 = [1,2,3,4];
        //传入一个回调函数
        const result = arr2.map(item => [item * 10]);
        const resultt = arr2.flatMap(item => [item * 10]);
        //一个二维数组
        console.log(result);
        //一个一维数组
        console.log(resultt);
    </script>

4、Symbol.prototype.description

概述: 获取Symbol的描述字符串;

<script>
        //创建 Symbol
        let s = Symbol('尚硅谷');

        console.log(s.description);//尚硅谷
    </script>

七、ES11 新特性

0、功能概述

1、String.prototype.matchAll 用来得到正则批量匹配的结果;

2、类的私有属性 私有属性外部不可访问直接;

3、Promise.allSettled 获取多个promise执行的结果集;

4、可选链操作符 简化对象存在的判断逻辑;

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

6、BigInt大整型;

7、globalThis 对象 始终指向全局对象window;

1、String.prototype.matchAll

概述: 用来得到正则批量匹配的结果;

<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];

        console.log(arr);
    </script>

2、类的私有属性

概述: 私有属性外部不可直接访问;

<script>
        class Person{
            //公有属性
            name;
            //私有属性
            #age;
            #weight;
            //构造方法
            constructor(name, age, weight){
                this.name = name;
                this.#age = age;
                this.#weight = weight;
            }

            //在内部声明方法
            show(){
                console.log(this.name);
                console.log(this.#age);
                console.log(this.#weight);
            }
        }

        //实例化
        const girl = new Person('晓红', 18, '45kg');

        console.log(girl)
        console.log(girl.name);
        //Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
        //console.log(girl.#age);
        //console.log(girl.#weight);

        //在外部访问
        girl.show();
    </script>

3、Promise.allSettled

概述:处理批量异步任务结果 获取多个promise执行的结果集; 

<script>
        //声明两个promise对象
        const p1 = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('商品数据 - 1');
            },1000)
        });

        const p2 = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                //resolve('商品数据 - 2');
                reject('出错啦!');
            },1000)
        });

        //调用 allsettled 方法
        //返回一个promise对象,其状态始终是成功的,成功的值是一个数组,包含p1, p2的状态和值
        const result = Promise.allSettled([p1, p2]);
        console.log(result)
        
        //返回一个promise对象
        //p1,p2都成功,则res成功,有一个失败,则失败。
        const res = Promise.all([p1, p2]);
        console.log(res);

    </script>

4、可选链操作符

概述: 如果存在则往下走,省略对对象是否传入的层层判断;

<script>
        // ?.
        function main(config){
            // const dbHost = config && config.db && config.db.host;

            //先判断config有没有传入,有再.db,如果有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>

5、动态 import 导入

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

html:引入app.js文件

 hello.js:导出模块

app.js:动态引用模块

 6、BigInt

概述: 更大的整数

<script>
        //大整形
        let n = 521n;
        console.log(n, typeof(n));//521n 'bigint'

        //函数
        let n1 = 123;
        //转换为BigInt
        console.log(BigInt(n1));//123n
        //Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is not an integer
        //console.log(BigInt(1.2));

        //大数值运算
        //最大安全整数
        let max = Number.MAX_SAFE_INTEGER;
        console.log(max);//9007199254740991
        console.log(max + 1);//9007199254740992
        console.log(max + 2);//9007199254740992

        console.log(BigInt(max))//9007199254740991n
        console.log(BigInt(max) + BigInt(1))//9007199254740992n
        console.log(BigInt(max) + BigInt(2))//9007199254740993n
    </script>

 

7、globalThis 对象

概述: 始终指向全局对象window; 

JavaScript环境:

node.js环境:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值