ES6基础

目录

前言

一、ECMASript相关介绍

1.什么是ECMA

2. 什么是ECMAScript

3. 什么是ECMA-262

4. ES6兼容性

二、ES6-变量声明

1.let

2.const(定义常量)

3. 变量的解构赋值 

4. 模板字符串

 5. 对象的简化写法

6. 箭头函数以及声明特点

7. 箭头函数的实践与应用场景 

8. 函数参数的默认值设置 

9. rest参数

10.扩展运算符

11.Symbol

11.1 Symbol的介绍与创建 

11.2 .对象添加Symbol类型的属性

11.3 Symbol内置属性

 12.迭代器的介绍

13. 生成器

13.1 生成器函数的声明与调用

 13.2 生成器函数参数

13.3 生成器函数实例 

 14. Promise

14.1 Promise介绍与基本使用

15. Set

16. Map 

17. Class类 

17.1 初体验

 17.2 class静态成员static

17.3 构造函数继承 

17.4 class中getter和setter设置

18. ES6数值扩展 

19. 对象方法扩展 

20.  模块化

20.1 模块化开发的好处

20.2 ES6模块化语法

 21. babel对ES6模块化代码转换

 22. ES6模块化引入NPM包

三、ES7新特性

1. Array.prototype.includes

2. 指数操作符

四、ES8新特性

1. async和await

1.1 async

1.2 await表达式

2. ES8对象方法扩展

五、ES9

1. 扩展运算符和rest参数 

 2. 正则扩展--命名捕获分组

3. 正则扩展--反向断言 

4. 正则扩展--dotAll模式 

六、ES10

1. Object.fromEntries()

2. 字符串扩展方法 

 3. 数组方法扩展

4. Symbol.prototype.description 

七、ES11 

1. 私有属性

2. Promise.allSettled

3. Strinprototype.matchAll()--得到正则批量匹配的结果

4. 可选链操作符 (?.)

5. 动态import 

6. BIgInt类型

7. globalThis--始终指向全局对象

八、参考资料


前言

课程介绍

  1. ES介绍(ES全称EcmsScript,是脚本语言的规范,而平时经常编写的jsvascript,是EcmaScript的一种实现,所以ES新特性其实指的就是javascript新特性)
  2. 为什么要学习ES新特性(1.语法简洁,功能丰富 2.框架开发应用 3.前端开发职位要求)
  3. 前置知识(1.JavaScript基础语法 2.JAX和NodeJS)
  4. 前置知识(1.由浅入深,通俗易懂 2.案例穿插)

一、ECMASript相关介绍

1.什么是ECMA

ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会。这个组织的目标是评估、开发和认可电信和计算机标准。1944年后该组织改名为Ecma国际

2. 什么是ECMAScript

ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言

3. 什么是ECMA-262

Ecma国际制定了许多标准,而ECMA-262只是其中的一种,所有的标准列表查看

ECMA-262 - Ecma International

4. ES6兼容性

ECMAScript 6 compatibility table可查看兼容性

二、ES6-变量声明

1.let

let a;
let b,c,d;
let e = 100;
let f = 520,g = "相思" , h = [];

特征
1. 变量不能重复声明;
2. 块级作用域、全局、函数、eval
例如:if else while for
    {
        let id = "超爱蓝莓汁"
    }
    console.log(id);  //报错:id is not defined
3. 不存在变量提升
4. 不影响作用域链
    {
        let id = "超爱蓝莓汁";
        function fn(){
            console.log(id);
        }
        fn()
    }
5. 案例
<style>
    .item{
        width: 100px;
        height: 100px;
        margin-left: 20px;
        border: 1px solid green;
        display:inline-block
    }
</style>
<div class="container">
    <h2 id="h2">点击切换颜色</h2>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
<script>
    let items = document.getElementsByClassName('item')
    for(let i=0 ; i<items.length ; i++){
        items[i].onclick = function(){
            items[i].style.background = "skyblue"
        }
    }
</script>

2.const(定义常量)

const ID = "超爱蓝莓汁";

特征
1. 一定要赋初始值;
    const A;(报错)
2. 一般常量用大写字母(潜规则) 
    const ID = "超爱蓝莓汁";
3. 常量的值不能修改  
    ID =  "超能陆战队"(报错) 
4. 块级作用域、全局、函数、eval
例如:if else while for
    {
        let ID= "超爱蓝莓汁"
    }
    console.log(ID); (报错)
5. 对于数组和对象的元素修改,不算做对敞亮的修改,不会报错
     const XIYOUJI = ["孙悟空", "猪八戒", "沙悟净"]
     XIYOUJI.push("唐玄奘")

3. 变量的解构赋值 

// ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
// 1. 数组的解构赋值
    const FAMILY = ["萨姗家族", "佐汌家族", "斯奈家族", "雪之一族"]
    let [萨姗, 佐汌, 斯奈, 雪] = FAMILY
    console.log(萨姗, 佐汌, 斯奈, 雪); //萨姗家族 佐汌家族 斯奈家族 雪之一族
// 2. 对象的解构赋值
    const HAIINYAN = {
        name: "海琴烟(冰公主)",
        age: 19,
        ability: function () {
            console.log("可以和动物交流");
        }
    }
    let { name, age, ability } = HAIINYAN;
    console.log(name, age) //海琴烟(冰公主) 19
    ability() //可以和动物交流

4. 模板字符串

// ES6 引入新的声明字符串的方式:反引号:``
// 1. 声明
    let str =`我也是字符串`
    console.log(typeof str,str);//string 我也是字符串
// 特性
    // 1. 内容中可以直接出现换行符
        let str1 = `<ul>
                        <li>郭德纲</li>
                        <li>岳云鹏</li>
                        <li>郭麒麟</li>
                    </ul>`
    // 2. 变量拼接
        let lovest = "郭麒麟";
        let out = `${lovest}是三个人中最年轻的`
        console.log(out); //郭麒麟是三个人中最年轻的

 5. 对象的简化写法

// ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的写法更简洁
// 1. 属性名和变量一样时可以如下简写
// 2. 函数可以去掉冒号和function:如:music(){}
    let author = "wlop";
    let work = function(){
        console.log("鬼刀");
    }
    const CHARACTER = {
        author,
        work,
        music(){
            console.log("GHOSTBLADE");
        }
    }
    console.log(CHARACTER);//{author: 'wlop', work: ƒ, music: ƒ}

6. 箭头函数以及声明特点

// ES6 允许使用【箭头】(=>)定义函数
// 1. 声明一个函数
    let fn = (a, b) => {
        return a + b
    }
    let result = fn(1, 2)
    console.log(result);//3
特性
// 1. this是静态的,this始终指向函数声明时所在作用域下的this的值
    function getName() {
        console.log(this.name);
    }
    let getName1 = () => {
        console.log(this.name);
    }
    //设置window对象的name属性
        window.name = "wlop";
        const WLOP = {
            name: "鬼刀"
        }
    //直接调用
        getName(); //wlop
        getName1();//wlop
    //call 方法调用
        getName.call(WLOP);//鬼刀
        getName1.call(WLOP);//wlop
// 2. 不能作为构造实例化对象
        // let Person=(name,age)=>{
        //     this.name = name
        //     this.age = age
        // }
        // let me = new Person("wlop",16)
        // console.log(me); //报错--Person is not a constructor
// 3. 不能使用arguments变量
        // let fun=()=>{
        //     console.log(arguments);
        // }
        // fun(1,2,3);//报错--arguments is not defined
// 4. 箭头函数的简写
    // 1). 省略小括号:当形参有且只有一个的时候
        let add = n => {
            return n+n
        }
        console.log(add(2));  //4
    // 2). 省略花括号:当代码体只有一条语句的时候,此时return也要省略,而且语句的执行结果就是函数的返回值
        let pow = n => n * n
        console.log(pow(9)); //81

7. 箭头函数的实践与应用场景 

<style>
    div {
        width: 200px;
        height: 200px;
        background: skyblue;
    }
</style>
<body>
    <div id="ad"></div>
    <script>
    // 需求-1 点击div 2s后颜色变成红色
        // 1. 获取元素
        let ad = document.getElementById("ad")
        // 2. 绑定事件
        ad.addEventListener("click", function () {
            //定时器
            setTimeout(() => {
                this.style.background = "red"
            }, 2000)
        })
    // 需求-2  从数组中返回偶数的元素
        const ARR = ["1", "2", "6", "8", "11", "13"]
        // const RESULT = ARR.filter(item => {
        //     if (item % 2 === 0) {
        //         return true
        //     } else {
        //         return false
        //     }
        // })
        const RESULT = ARR.filter(item => item % 2 === 0)
        console.log(RESULT);
        // 
        // 1.适合场景 与this无关的回调:定时器、数组方法的回调
        // 2.不合适场景:与this有关的回调:事件回调、对象的方法
    </script>
</body>

8. 函数参数的默认值设置 

// ES6 允许给函数参数赋值初始值
// 1. 形参的初始值:具有默认值的参数,一般放在最后面(潜规则)
        function add(a, b, c = 10) {
            return a + b + c
        }
        let result = add(1, 2)
        let result1 = add(1, 2, 3)
        console.log(result); //13
        console.log(result1); //6
// 2. 与解构赋值相结合使用
1):
    function connect({ host, userName ,password,port}) {
        console.log(host); // localhost
        console.log(userName,password,port)
    }
    connect({
        host: "localhost",
        userName: "root",
        password: "root",
        port: "3306"
    })

2):
    function connect1({ host="baidu.com", userName,password,port }) {
        console.log(host); //baidu.com
        console.log(userName,password,port)
    }
    connect1({
        userName: "root",
        password: "root",
        port: "3306"
    })

9. rest参数

// ES6 引入rest参数  用于获取函数的实参,用于代替arguments
// ES5获取实参的方式
    function date(){
        console.log(arguments);
    }
    date("黑圣堂","白圣堂","血天使") 
    //Arguments(3) ['黑圣堂', '白圣堂', '血天使', callee: ƒ, Symbol(Symbol.iterator): ƒ]
// ES6获取rest参数
    function character(...args){
        console.log(args);
    }
    character("黑圣堂","白圣堂","血天使") // ['黑圣堂', '白圣堂', '血天使']
// 注意:rest参数必须要存放在参数的最后
    function fn(a,b,...args){
        console.log(a); //1
        console.log(b); //2
        console.log(args); // [3, 4, 5, 6, 7, 8]
    }
    fn(1,2,3,4,5,6,7,8)

10.扩展运算符

<body>
    <div></div>
    <div></div>
    <div></div>
    <script>
        // 【...】扩展运算符能将【数组】转换为逗号分割的【参数序列】
        // 1. 介绍
            //声明一个数组
                const TFBOYS = ["王俊凯", "王源", "易烊千玺"]
            //声明一个函数
                function chunwan() {
                    console.log(arguments);
                }
                chunwan(...TFBOYS)
        // 2. 应用
            // 1):数组的合并
                const ANIMATION = ["海绵宝宝","章鱼哥","派大星"]
                const MUSIC = ["凤凰传奇","Twins","五月天"]
                const combination=[...ANIMATION,...MUSIC]
                console.log(combination);
                //['海绵宝宝', '章鱼哥', '派大星', '凤凰传奇', 'Twins', '五月天']
            // 2):数组的克隆
                const LETTER = ["A","B","D"]
                const clone = [...LETTER]
                console.log(clone);//["A","B","D"]
            // 3):将伪数组转为真正的数组
                const divs = document.querySelectorAll("div")
                const divArr = [...divs]
                console.log(divArr);//[div, div, div]
    </script>
</body>

11.Symbol

11.1 Symbol的介绍与创建 

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

  1.  Symbol的只是唯一的,用来解决命名冲突的问题
  2. Symbol值不能与其他数据进行运算
  3. Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
    // 1. 创建Symbol
        let s = Symbol()
        console.log(s, typeof s); //Symbol() 'symbol'
    
        let s2 = Symbol("wlop")
        let s3 = Symbol("wlop")
        console.log(s2 == s3); //false
    
        let s4 = Symbol.for("wlop")
        console.log(s4, typeof s4); //Symbol(wlop) 'symbol'
    
        let s5 = Symbol.for("wlop")
        console.log(s4 === s5); //true
    // 2. 不能与其他数据进行运算
        // let result = s + 100 //报错--Cannot convert a Symbol value to a number
        // let result1 = s > 100  //报错--Cannot convert a Symbol value to a number
        // let result3 = s + s  //报错--Cannot convert a Symbol value to a number
    
    
    数据类型:USONB---you are so niubility
    u:undefined
    s:string  symbol
    o:object
    n:null  number
    b:boolean

11.2 .对象添加Symbol类型的属性

// 给对象添加Symbol类型的属性
// 第一种:
        let game={
            name:"wlop",
            up(){},
            down(){}
        }
        //声明一个对象
        let methods={
            up:Symbol(),
            down:Symbol()
        }
        game[methods.up]=function(){
            console.log("up方法");
        }
        game[methods.down]=function(){
            console.log("down方法");
        }
        console.log(game);
// 第二种:
        let youxi ={
            name:"狼人杀",
            [Symbol("say")](){
                console.log("我可以发言");
            },
            [Symbol("zibao")](){
                console.log("我可以自爆");
            }
        }
        console.log(youxi);

11.3 Symbol内置属性

具体属性详情:Symbol - JavaScript | MDN

// 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
        let arr = [1,2,3]
        let list = [4,5,6]
        console.log(arr.concat(list));//[1, 2, 3, 4, 5, 6]
        list[Symbol.isConcatSpreadable]=false;
        console.log(arr.concat(list)); //[1, 2, 3, Array(3)]
// 3. 具体其他属性可点击链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol

 12.迭代器的介绍

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

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

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

  1. Array
  2. Arguments
  3. Set
  4. Map
  5. String
  6. TypedArray
  7. NodeList

3. 工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
  4. 每调用next方法返回一个包含value和done属性的对象

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

//声明一个数组
    const  xiyouji = ["唐玄藏","孙悟空","猪八戒","沙悟净"]
    // 1. 使用 for...of循环---保存的是键值
        for(let i of xiyouji){
            console.log(i); //唐玄藏 孙悟空 猪八戒  沙悟净
        }
    // 2. 使用 for...in循环---保存的是键名
        for(let i in xiyouji){
            console.log(i);// 0 1 2 3
        }

//工作原理
    let iterator = xiyouji[Symbol.iterator]()
    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}



//应用
    // 需求-1  使用for...of遍历,每次返回的结果是数组里面的每个成员
    //声明一个对象
    const wlop = {
        name: "鬼刀",
        character: [
            "黑圣堂",
             "白圣堂-卡塔利斯",
             "血天使-奥斯丁",
             "天剑-南风",
        ],
        [Symbol.iterator](){
            //索引变量
            let index = 0
            let self = this
            return {
               next(){
                 if(index<self.character.length){
                   const result = {value:self.character[index],done:false}
                   //下标自增
                   index++
                   //返回结果
                    return result
                  }else{
                    return {value:undefined,done:true}
                   }
                }
              };
            }
        }
        //遍历这个对象
        for(let i of wlop){
            console.log(i);  // 黑圣堂 白圣堂-卡塔利斯 血天使-奥斯丁 天剑-南风
        }

13. 生成器

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

13.1 生成器函数的声明与调用

//生成器其实就是一个特殊的函数
// 1. 生成器函数的声明与调用
    function* gen() {
            // console.log("Hello 风铃");
        yield "风铃"
            // console.log("Hello 风曳");
        yield "风曳"
            // console.log("Hello 海琴烟(冰公主)");
        yield "海琴烟(冰公主)"
            // console.log("hello 鬼刀");
    }
    let iterator = gen()
    // iterator.next();  // Hello 风铃
    // iterator.next();  // Hello 风曳
    // iterator.next();  // Hello 海琴烟(冰公主)
    // iterator.next();  // Hello 鬼刀

    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 i of gen()) {
            console.log(i);  //风铃 风曳 海琴烟(冰公主)
        }

 13.2 生成器函数参数

// 2. 生成器函数参数
    function* generator(arg) {
            console.log(arg);  //黑圣堂
        let one =yield "燃焰玫瑰-云娜"
            console.log(one); //大祭司-艾尔萨拉
        let two = yield "独狼-西凌斯"
            console.log(two);  //大漠泰坦-洪都
        let three = yield "银白-卡因"
            console.log(three);  //天都
    }
    //执行获取迭代器对象
    let iterator1 = generator("黑圣堂")
    console.log(iterator1.next());
    // next方法可以传入实参
    console.log(iterator1.next("大祭司-艾尔萨拉")); //将作为第一个yield语句的返回结果
    console.log(iterator1.next("大漠泰坦-洪都"));//将作为第二个yield语句的返回结果
    console.log(iterator1.next("天都"));//将作为第三个yield语句的返回结果

13.3 生成器函数实例 

// 需求 -1   1s后控制台输出111  2s后输出222   3s后输出333
    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();

// 需求 -2   模拟获取:用户数据、订单数据、商品数据
    function getUsers() {
        setTimeout(() => {
            let data = "用户数据";
            //调用next方法并把数据传入
            iterator1.next(data);
        }, 1000)
    }
    function getOrders() {
        setTimeout(() => {
            let data = "订单数据";
            iterator1.next(data);
        }, 1000)
    }
    function getGoods() {
        setTimeout(() => {
            let data = "商品数据"
            iterator1.next(data);
        }, 1000)
    }
    function* generator() {
        let users = yield getUsers()
        console.log(users);
        let orders = yield getOrders()
        console.log(orders);
        let goods = yield getGoods()
        console.log(goods);
    }
    //调用生成器函数
    let iterator1 = generator()
    iterator1.next();

 14. Promise

详情:Promise - JavaScript | MDN

视频学习:尚硅谷Web前端Promise教程从入门到精通_哔哩哔哩_bilibili

视频学习做的笔记

  1. Promise基础(上)_超爱蓝莓汁的博客-CSDN博客
  2. Promise基础(下)_超爱蓝莓汁的博客-CSDN博客

Promise是ES6引入的异步编程的新的解决方案。

语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或者失败的结果

  1. Promise构造函数:Promise(excutor){}
  2. Promise.prototype.then()方法
  3. Promise.prototype.catch()方法

14.1 Promise介绍与基本使用

//实例化Promise对象
        const P = new Promise((reslve, reject) => {
            setTimeout(() => {
                //数据读取成功的
                // let data = "数据库中的用户数据";
                // reslve(data)
                //数据读取失败的
                let error = "数据读取失败";
                reject(error)

            }, 1000)
        })
        P.then(res=> {
            //成功的回调
            console.log(res); //数据库中的用户数据
        }).catch(error => {
            console.log(error);  //数据读取失败
        })
// 1. Promise封装AJAX请求
        const P = new Promise((resolve, reject) => {
            // a:创建对象
            const xhr = new XMLHttpRequest()
            // b:初始化
            xhr.open("GET", "https://api.apiopen.top/getJoke")
            // c:发送
            xhr.send()
            // d:绑定事件,处理响应结果
            xhr.onreadystatechange = function () {
                //判断
                if (xhr.readyState === 4) {
                    //判断响应状态吗
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //表示成功
                        resolve(xhr.response)
                    } else {
                        reject(xhr.status)
                    }
                }
            }
        })
        P.then(res=>{
            console.log(res);
        }).catch(error=>{
            console.error(error);
        })

15. Set

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

集合的属性和方法

  1. size:返回集合的元素个数
  2. add:增加一个新元素,返回当前合集
  3. delete:删除元素,返回boolean值
  4. has:检测集合中是否包含某个元素,返回boolean值
  5. clear:清空合集,返回undefined
//声明一个集合
let s = new Set()
console.log(s,typeof s);  //Set(0) 'object'
let s1= new Set([1,2,3,4,1,2])
console.log(s1);  //Set(4) {1, 2, 3, 4}
// 1. 元素的个数:size
console.log(s1.size);  //4
// 2. 添加元素add
s1.add(6)
console.log(s1);  //Set(5) {1, 2, 3, 4, 6}
// 3. 删除 delete
s1.delete(6)
console.log(s1);  //Set(4) {1, 2, 3, 4}
// 4. 检测has
console.log(s1.has(1));  //true
console.log(s1.has(6));  //false
// 5. 清空clear
// s1.clear()
// console.log(s1);  //Set(0) {size: 0}
// 遍历
for(let i of s1){
    console.log(i);  // 1 2 3 4
}
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 arr1 = [4, 5, 6, 5, 6]
let result1 = [...new Set(arr)].filter(item => new Set(arr1).has(item))
console.log(result1);  // [4, 5]
// 需求 -3 并集
let arr2 = [4, 5, 6, 5, 6]
let result2 = [...new Set([...arr, ...arr2])]
console.log(result2);  // [1, 2, 3, 4, 5, 6]
// 需求 -4 差集
let arr3 = [4, 5, 6, 5, 6]
let result3 = [...new Set(arr)].filter(item => !(new Set(arr1).has(item)))
console.log(result3);  //  [1, 2, 3]

16. Map 

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

Map的属性和方法

  1. size:返回Ma的元素个数
  2. set:增加一个新元素,返回当前Map
  3. get:返回键名对象的键值
  4. has:检测Map中是否包含某个元素,返回boolean值
  5. clear:清空合集,返回undefined
//声明Map
let m = new Map()
console.log(m, typeof m);  //Map(0) {size: 0} 'object'
// 1. 添加元素set
m.set("name","wlop")
console.log(m);  //Map(1) {'name' => 'wlop'}
m.set("change",function(){ console.log("I Loe You"); })
console.log(m);  //Map(2) {'name' => 'wlop', 'change' => ƒ}
let key = {
    work:"鬼刀"
}
m.set(key,["北京","杭州","深圳"])
console.log(m);  //Map(3) {'name' => 'wlop', 'change' => ƒ, {…} => Array(3)}
// 2. 元素个数size
console.log(m.size); // 3
// 3. 删除元素delete
m.delete('name')
console.log(m);  //Map(2) {'change' => ƒ, {…} => Array(3)}
// 4. 获取get
console.log(m.get("change"));  //ƒ (){ console.log("I Loe You"); }
console.log(m.get(key));  //['北京', '杭州', '深圳']
// 5. 清空clear
// m.clear()
// console.log(m);  //Map(0) {size: 0}
// 遍历
for(let i of m){
    console.log(i);  
//  ['北京', '杭州', '深圳'] 、 ['change', ƒ] 、 [{…}, Array(3)]
}

17. Class类 

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

知识点:

  1. class声明类
  2. constructor定义构造函数初始化
  3. extends继承父类
  4. super调用父级构造方法
  5. static定义静态方法和属性
  6. 父类方法可以重写

17.1 初体验

// 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 Phone1 {
    //构造方法
    constructor(brand, price) {
        this.brand = brand
        this.price = price
    }
    //方法必须使用该语法,不能使用ES5的完整对象形式
    call(){
        console.log("我可以打电话");
    }
}
let OPPO = new Phone1("OPPO",4999)
OPPO.call()  //我可以打电话
console.log(OPPO);  //Phone1 {brand: 'OPPO', price: 4999}

 17.2 class静态成员static

class Phone{
    static name="手机"
    static cahnge(){
        console.log("我可以改变世界");
    }
}
let nokia = new Phone()
console.log(nokia.name);  //undefined
console.log(Phone.name);  //手机

17.3 构造函数继承 

class Wlop {
    //构造方法
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    //父类的成员属性
    call() {
        console.log("鬼刀");
    }
}
class Fans extends Wlop {
    //构造方法
    constructor(name, age, ability, arms) {
        super(name, age)
        this.ability = ability
        this.arms = arms
    }
    occupation() {
        console.log("职业");
    }
    city() {
        console.log("城市");
    }
    call(){
        console.log("子类自己的方法")
    }
}
const character = new Fans("海琴烟", 18, "和动物交流", "手")
character.call()  
// 子类没有call方法时打印:鬼刀    --- 子类有自己的call方法时打印:子类自己的方法
character.occupation()  //职业
character.city()  //城市
console.log(character);  
//Fans {name: '海琴烟', age: 18, ability: '和动物交流', arms: '手'}


 子类对父类方法的重写 
就是就近原则:如果子类中有和父级同名的方法,则会调用自己的方法

17.4 class中getter和setter设置

class Wlop {
    // 对对象的动态属性进行封装
    get work() {
        console.log("作品");
        return "I Love You"
    }
    //set必须要有一个参数
    // 添加控制、判断
    set work(newVal) {
        console.log("设置作品");
    }
}
//实例化对象
let w = new Wlop()
console.log(w.work);  // 函数里面的返回值就是属性的值
w.work = "鬼刀"  // 设置后会执行打印:设置作品

18. ES6数值扩展 

具体详情:Number - JavaScript | MDN

// 1. Number.EPSILON 是 JavaScript 表示的最小精度---误差如果小于这个值,就近似于相等
// 作用:浮点数计算,对精度进行设置
console.log(0.1 + 0.2);  // 0.30000000000000004
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
// 2. 二进制和八进制
// 1):二进制
let b = 0b1010
console.log(b);  // 10
// 2):八进制
let o = 0o777;
console.log(o);  // 511
// 3):十进制
let d = 100;
console.log(d);  // 100
// 4):十六进制
let x = 0xff;
console.log(x);  // 255
// 3. Number.isFinite  检测一个数值是否为有限数
console.log(Number.isFinite(100));  // true
console.log(Number.isFinite(Infinity));  // false
// 4. Number.isNaN  检测一个数值是否为NaN
console.log(Number.isNaN(123));  // false
console.log(Number.isNaN(NaN));  // true
// 5. Number.parseInt   Number.parseFloat  字符串转整数(数字)
console.log(Number.parseInt("521我爱你"));  // 521
console.log(Number.parseFloat("3.1415926派"));  // 3.1415926
// 6. Number.isInteger   判断一个数是否为整数
console.log(Number.isInteger(5));  // true
console.log(Number.isInteger(5.2));  // false
// 7. Math.trunc   将数字的小数部分抹去
console.log(Math.trunc(5.2));  // 5
// 8. Math.sign   判断一个数到底为正数、负数、还是零
console.log(Math.sign(-6));  // -1
console.log(Math.sign(6));  // 1
console.log(Math.sign(0));  // 0

19. 对象方法扩展 

具体详情:Object - JavaScript | MDN

// 1. Object.is  判断两个值是否完全相等
console.log(Object.is(120, 121));  //false
console.log(Object.is(120, "120"));  //false
console.log(Object.is(NaN, NaN));  //true
console.log(NaN === NaN);  //false
// 2. Object.assign  对象的合并
const config1 = {
    host: "localhost",
    port: "3306",
    name: "root",
    password: "root"
}
const config2 = {
    host: "www.baidu.com",
    port: "8080",
    name: "百度",
    // password: "root"
}
console.log(Object.assign(config1, config2));
// {host: 'www.baidu.com', port: '8080', name: '百度', password: 'root'}
// 3. Object.setPrototypeOf--设置原型对象  Object.getPrototypeOf--湖获取原型
const wlop = {
    name: "鬼刀"
}
const character = {
    charact: ["天僧-皓月", "凯烈", "贝依"]
}
Object.setPrototypeOf(wlop, character)
console.log(wlop);
console.log(Object.getPrototypeOf(wlop));  //{charact: Array(3)}

20.  模块化

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

20.1 模块化开发的好处

  1. 防止命名冲突
  2. 代码复用
  3. 高维护性

20.2 ES6模块化语法

模块功能主要有两个命令构成:export 和 import

  • export 命令用于规范模块的对外接口
  • import 命令用于输入其他模块提供的功能
<script type="module">
1. 通用的导入方式
    import * as m from "./m.js"
    console.log(m);
    console.log(m.author);  //wlop
    import * as m1 from "./m1.js"
    console.log(m1);
    m1.work1();  //鬼刀
    import * as m2 from "./m2.js"
    console.log(m2);
    m2.default.work2()  //鬼刀

2. 解构赋值形式
    import {author,work} from "./m.js"
    console.log(author);  // wlop
    console.log(work);  //ƒ work() { console.log("鬼刀");}
    import {author as name,work1} from "./m1.js"  //重名的话可以使用 as 重命名
    console.log(name);  // wlop
    console.log(work1);  //ƒ work() { console.log("鬼刀");}
    import {default as def} from "./m2.js"  //不能直接使用default,需要重命名
    console.log(def);  // {author2: 'wlop', work2: ƒ}

3. 简便形式(只能针对默认暴露)
    import defa from './m2.js'
    console.log(defa);  // {author2: 'wlop', work2: ƒ}
    import part from './m.js'
    console.log(part);  
//报错--Uncaught SyntaxError: 
//The requested module './m.js' does not provide an export named 'default'

</script>

m.js
//分别暴露
    export let author = "wlop";
    export function work() {
      console.log("鬼刀");
    }

m1.js
// 统一暴露
    let author1 = "wlop";
    function work1() {
      console.log("鬼刀");
    }
    export { author1, work1 };  // 对象简写

m2.js
//默认暴露
// 暴露可以是任意类型:数字、对象、函数...(对象居多)
    export default{
        author2:"wlop",
        work2(){
            console.log("鬼刀");
        }
    }


运行时报错(CORS 跨域报错)
Access to script at 'file:///E:/sunli/desktop/proctice/m1.js' 
from origin 'null' has been blocked by CORS policy: Cross origin 
requests are only supported for protocol schemes:
http, data, chrome, chrome-extension, chrome-untrusted, https.

解决方法:
1. Vscode下载插件:Live Server
2. 右键html文件:Open with Live Server

 浏览器使用ES6模块化语法二

新建一个入口文件app.js,把import 的引入全部放在app.js中,在htm文件中直接src引入

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

 21. babel对ES6模块化代码转换

babel官网:Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器

        *   需要安装工具  

-  babel-cli:babel命令行工具  

-  babel-preset-env:预设包-能够转换成es5语法  

-  browserify:打包工具(webpack)

        * 1. 先初始化:npm i

        * 2. 安装工具:npm i babel - cli babel - preset - env browserify - D

        * 3. npx babel js -d dist/js --presets=babel-preset-env

        * 4. 打包:npx browserify dist/js/app.js -o dist/bundle.js

        * 5. 在页面中引入:<script src="dist/bundle.js"></script>

 

 22. ES6模块化引入NPM包

  1. 安装所需要的依赖包:npm i 包
  2. 在需要的页面引入:import 名称 from "包"

三、ES7新特性

1. Array.prototype.includes

includes方法用来检测数组中是否包含某个元素,返回布尔类型值

let mingzhu = ["西游记","红楼梦","三国演义","水浒传"]
console.log(mingzhu.includes("西游记"));  // true
console.log(mingzhu.includes("金瓶梅"));  // false

2. 指数操作符

在ES7中引入指数运算符【**】,用来实现幂运算,功能与Math.pow结果相同

console.log(2**10);  //1024
console.log(Math.pow(2,10));  //1024

四、ES8新特性

1. async和await

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

1.1 async

  1. async函数的返回值为promise对象
  2. promise对象的结果由async函数执行的返回值决定
// async 函数
async function func() {
    // 1. 返回一个非promise对象
    // return "wlop"
//只要返回的结果不是一个promise类型的对象,则这个函数的返回结果就是成功的promise
    // 2. 抛出错误
    // throw new Error("出错了")
    // 3. 返回的结果就是一个promise对象
    return new Promise((resolve, reject) => {
        // resolve("成功了")
        reject("失败了")
    })
}
const result = func()
console.log(result);  //Promise {<fulfilled>: 'wlop'}
result.then(res => {
    console.log(res);
}).catch(error => {
    console.log(error);
})

1.2 await表达式

  1. await必须写在async函数中
  2. await右侧的表达是一般为promise对象
  3. await返回的promise成功的值
  4. await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
// await 要放在async函数中,但是async里面可以没有await
const P = new Promise((resolve, reject) => {
    // resolve("success")
    // resolve("用户数据")
    reject("失败了")
})
async function main() {
    try {
        let result = await P
        // console.log(result);  // success
        // console.log(result);  // 用户数据
    } catch (error) {
        console.log(error);  //失败了
    }
}
main()

2. ES8对象方法扩展

  1.  Object.values();
  2. Object.entries();
  3. Object.getOwnPropertyDescriptors();
// 1.  Object.values和Object.entries
// Object.values()方法返回一个给定对象的所有可枚举属性值的数组
// Object.entries()方法返回一个给定对象自身可遍历属性【key,value】的数组
const wlop = {
    name: "鬼刀",
    character: ["黑圣堂", "白圣堂", "血天使", "南风"],
    arms: ['修罗', '鬼刀', '叹息', '流光(已毁)', '审判', '彷徨', '魔灵', '狂砂', '血刺(已毁)', '新月']
}
// 获取对象所有的键
console.log(Object.keys(wlop));  // ['name', 'character', 'arms']
// 获取对象所有的值
console.log(Object.values(wlop));  // ['鬼刀', Array(4), Array(10)]
// entries
console.log(Object.entries(wlop));  // [Array(2), Array(2), Array(2)]
// 创建Map
const m = new Map(Object.entries(wlop))
console.log(m);  // Map(3) {'name' => '鬼刀', 'character' => Array(4), 'arms' => Array(10)}
console.log(m.get("name"));  // 鬼刀
console.log(m.get("character"));  // ['黑圣堂', '白圣堂', '血天使', '南风']
// 2. Object.getOwnPropertyDescriptors 该方法返回指定对象所有自身属性的描述对象【可以进行对象深层次的克隆】
console.log(Object.getOwnPropertyDescriptors(wlop));  //{name: {…}, character: {…}, arms: {…}}
const obj = Object.create(null, {
    name: {
        //设置值
        value: "海琴烟",
        //属性特征
        writable: true,  // 是否可写
        configurable: true,  // 是否可以删除
        enumerable: true,  // 是否可以枚举

    }
})

五、ES9

1. 扩展运算符和rest参数 

// rest参数与spread扩展运算符在ES6中已经引入,但只是针对数组
// 在ES9中为对象提供了向数组一样的rest参数和扩展运算符
// 1. rest参数
function connect({host,post,...user}){
    console.log(host,post,user);  
// 127.0.0.1 3306 {username: 'root', password: 'root', type: 'master'}
}
const obj = {
    host:"127.0.0.1",
    post:3306,
    username:"root",
    password:"root",
    type:"master"
}
connect(obj)
// 2. 扩展运算符
const wlop1 = {arms1:"鬼刀"}
const wlop2 = {arms2:"修罗"}
const wlop3 = {arms2:"叹息"}
const wlop4 = {arms3:"审判"}
const arms = {...wlop1,...wlop2,...wlop3,...wlop4}
console.log(arms);  //{arms1: '鬼刀', arms2: '叹息', arms3: '审判'}

 2. 正则扩展--命名捕获分组

//需求 -1 提取url与【标签文本】
//声明一个字符串
let str = '<a href="https:www.baidu.com">百度</a>'
//一: 之前的方法
const reg1 = /<a href="(.*)">(.*)<\/a>/
// // 执行
const result1 = reg1.exec(str)
console.log(result1);
// //['<a href="https:www.baidu.com">百度</a>', 'https:www.baidu.com', '百度', index: 0, input: '<a href="https:www.baidu.com">百度</a>', groups: undefined]
// // 1. 第零个元素;是整个正则匹配的结果。
// // 2. 第一个元素:是第一个小括号匹配到的结果,
// // 3. 第二个元素:是第二个小括号匹配到的结果
console.log(result1[1]);  //https:www.baidu.com
console.log(result1[2]);  //百度

// 二:命名捕获分组方法
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/
const result = reg.exec(str)
console.log(result);
//['<a href="https:www.baidu.com">百度</a>', 'https:www.baidu.com', '百度', index: 0, input: '<a href="https:www.baidu.com">百度</a>', groups: {…}]
console.log(result.groups.url);  //https:www.baidu.com
console.log(result.groups.text);  //百度

3. 正则扩展--反向断言 

let str = 'GSJJ1654的就是不对接口215佛挡杀'
// 一、正向断言
const reg = /\d+(?=佛)/
const result = reg.exec(str)
console.log(result);
//['215', index: 15, input: 'GSJJ1654的就是不对接口215佛挡杀', groups: undefined]
// 二、反向断言
const reg1 = /(?<=口)\d+/
const result1 = reg1.exec(str)
console.log(result1);
// ['215', index: 15, input: 'GSJJ1654的就是不对接口215佛挡杀', groups: undefined]

4. 正则扩展--dotAll模式 

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>/s
const result = reg.exec(str)
console.log(result);

const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
let result2
let data = []
while (result2 = reg2.exec(str)) {
    console.log(result2);
    data.push({ title: result2[1], time: result2[2] })
}
console.log(data);

六、ES10

1. Object.fromEntries()

// Object.fromEntries:创建一个对象,接收参数是一个二维数组或者一个Map
// 二维数组
const result = Object.fromEntries([
    ['name', "海琴烟"],
    ['arms', '修罗, 鬼刀, 叹息,  流光(已毁), 审判, 彷徨, 魔灵, 狂砂, 血刺(已毁), 新月']
])
console.log(result);
//{name: '海琴烟', arms: '修罗, 鬼刀, 叹息,  流光(已毁), 审判, 彷徨, 魔灵, 狂砂, 血刺(已毁), 新月'}
//Map
const m = new Map();
m.set("name","鬼刀")
const result1 = Object.fromEntries(m)
console.log(result1);  //{name: '鬼刀'}

2. 字符串扩展方法 

  1. trimStart()----清除字符串左侧空格
  2. trimEnd()---清除字符串右侧空格
let str = "   I Love You  "
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());

 3. 数组方法扩展

  1. flat
  2. flatMap
// flat:将多维数组转为低维数组
const arr= [1,2,3,[4,5,6]]
console.log(arr.flat());  //[1, 2, 3, 4, 5, 6]
const arr1=  [1,2,[3,4,[5,6,7]]] 
console.log(arr1.flat());   //[1, 2, 3, 4, Array(3)]
console.log(arr1.flat(2));   //[1, 2, 3, 4, 5, 6, 7]
const arr2 =[1,2,3]
console.log(arr2.flatMap(item=>[item*10]));  // [10, 20, 30]
//多维数组转一维数组
const list = [1,2,3,[4,5,6,[7,8,9,[10,11,12,[13,14,15]]]]]
console.log(list.flat(Infinity)); 
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

4. Symbol.prototype.description 

let wlop = Symbol("鬼刀")
console.log(wlop.description);  //鬼刀

七、ES11 

1. 私有属性

class Person {
    // 公有属性
    name;
    //私有属性
    #age;
    #weight;
    //构造方法
    constructor(name, age, weight) {
        this.name = name
        this.#age = age
        this.#weight = weight
    }
    intro() {
        console.log(girl.name);  //芙不乖
        console.log(girl.#age); // 18
        console.log(girl.#weight);  // 45kg

    }
}
//实例化对象
const girl = new Person("芙不乖", 18, '45kg')
// console.log(girl.name);  //芙不乖
// console.log(girl.#age); // 语法报错 --undefined
// console.log(girl.#weight);  // 语法报错--undefined
girl.intro()

2. Promise.allSettled

 返回的结果状态始终是成功的,成功的值是每个promise执行的结果值和状态

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("商品数据 -1")
    }, 1000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("商品数据 -2")
        // reject("出错了")
    }, 1000)
})
const  result = Promise.allSettled([p1,p2])
console.log(result);
//返回的结果状态始终是成功的,成功的值是每个promise执行的结果值和状态

3. Strinprototype.matchAll()--得到正则批量匹配的结果

// Strinprototype.matchAll:得到正则批量匹配的结果
let str = `
    <ul>
        <li>
            <a>肖申克的救赎</a>
            <p>上映时间:1994-09-10</p>
        </li>
        <li>
            <a>阿甘正传</a>
            <p>上映时间:1994-07-06</p>
        </li>
    </ul>
    `
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
const result = str.matchAll(reg)
console.log(result);
// for(let i of result){
//     console.log(i);
// }
const arr = [...result]
console.log(arr);

4. 可选链操作符 (?.)

function main(config){
    const dbHost = config?.db?.host
    console.log(dbHost);  //127.0.0.1
}
main({
    db:{
        host:"127.0.0.1",
        port:3306
    },
    cache:{
        host:"192.168.10.111",
        port:8080
    }
})

5. 动态import 

import('./app.js').then(()=>{
  console.log('动态引入');
});

6. BIgInt类型

详情:BigInt - JavaScript | MDN

7. globalThis--始终指向全局对象

详情:globalThis - JavaScript | MDN

console.log(globalThis);

八、参考资料

视频:尚硅谷Web前端ES6教程,涵盖ES6-ES11_哔哩哔哩_bilibili

文档:1. ES6 入门教程

正则MDN文档:RegExp(正则表达式) - JavaScript | MDN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值