ECMAScript(ES6)

ECMAScript

ECMAScrit 简介

  • ECMAEuropean Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为Ecma国际。
  • ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言
  • Ecma国际制定了许多标准,而ECMA-262只是其中的一个,所有标准列表查看
  • http://www.ecma-international.org/publications/standards/Standard.htm

ECMA-262 历史

  • ECMAEuropean Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信

    第 1 版 1997年 制定了语言的基本语法
    第 2 版 1998年 较小改动
    第 3 版 1999年 引入正则、异常处理、格式化输出等。IE 开始支持
    第 4 版 2007年 过于激进、未发布
    第 5 版 2009年 严格模式、JSON、扩展对象、数组、原型、字符串、日期方法
    第 6 版 2015年 模块化、面向对象语法、Promise、箭头函数、letconst、数组解构赋值等等
    第 7 版 2016年 幂运算符、数组扩展
    第 8 版 2017年 Async/await、字符串扩展
    第 9 版 2018年 对象解构赋值、正则扩展
    第 10 版 2019年 扩展对象、数组方法
    ES.next 动态指向下一个版本
  • 注:从ES6开始,每年发布一个版本,版本号比年份最后一位大 1

为什么要学习ES6

  • ES6的版本变动内容最多,具有里程碑意义
  • ES6加入许多新的语法特性,编程实现更简单、高效
  • ES6是前端发展趋势,就业必备技能

let 关键字

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

    • 不允许重复声明

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // 不允许重复声明
          let a = 10;
          // let a = "abc"; // 报错
          console.log(a); // 10
        </script>
      </html>
      
    • 块儿级作用域

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // 块儿级作用域 for if
          // var 是没有块级作用域的
          for (var i = 0; i < 10; i++) {
                
                }
          console.log(i); // 10
          if (true) {
                
                
            var f = "abc";
          }
          console.log(f); // abc
          // let 是没有块级作用域的
          for (let index = 0; index < 10; index++) {
                
                }
          // console.log(index); // 报错 index is not defined
          if (true) {
                
                
            let n = false;
          }
          // console.log(n); // 报错 n is not defined
        </script>
      </html>
      
    • 不存在变量提升

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // var 的变量提升
          console.log(a); //undefined
          var a = 10;
      
          // let 不存在变量提升
          // console.log(n); // 报错 Cannot access 'n' before initialization
          let n = false;
        </script>
      </html>
      
    • 不影响作用域链

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // var 不影响作用域链
          function fn() {
                
                
            var a = 10;
            function fn1() {
                
                
              var b = 10;
              console.log(a + b); // 20
            }
            function fn2() {
                
                
              var c = 20;
              // console.log(a + b + c); // 报错 b is not defined
            }
            fn1();
            fn2();
          }
          // fn();
      
          // let 也不影响作用域链
          function foo() {
                
                
            let a = 10;
            function fn1() {
                
                
              let b = 10;
              console.log(a + b); // 20
            }
            function fn2() {
                
                
              let c = 20;
              // console.log(a + b + c); // 报错 b is not defined
            }
            fn1();
            fn2();
          }
          foo();
        </script>
      </html>
      
  • 应用场景:以后声明变量使用let就对了

const 关键字

  • const关键字用来声明常量,const声明有以下特点

    • 声明必须赋初始值

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // const a; // 报错 Missing initializer in const declaration
          const a = 10;
          console.log(a); // 10
        </script>
      </html>
      
    • 标识符一般为大写

    • 不允许重复声明

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          const a = false;
          // const a = 10; // 报错 Identifier 'a' has already been declared
          console.log(a); // false
        </script>
      </html>
      
    • 值不允许修改

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          const a = false;
          // a = 10; // 报错 Assignment to constant variable.
          console.log(a);
        </script>
      </html>
      
    • 块儿级作用域

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          for (let i = 0; i < 10; i++) {
                
                
            const a = 20;
            var b = 10; // var 定义的变量在for循环中是没有块级作用域的
          }
          // console.log(a); // 报错 a is not defined
          console.log(b); // 10
      
          if (true) {
                
                
            const foo = false;
          }
          console.log(foo); // 报错 foo is not defined
          // const 在 for 和 if 都是具有块级作用域的
        </script>
      </html>
      
  • 注意: 对象属性修改和数组元素变化不会触发const错误

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    // 对象属性改变不会触发 const 错误
    const obj = {
      
      
      name: "张三",
      age: 10,
      sayHi: function () {
      
      
        console.log(this.name + ":hi");
      },
    };
    obj.name = "王五";
    obj.sayHi(); // 王五:hi
    obj.weight = "50";
    console.log(obj); // 也不会报错

    // 数组元素改变也不会触发 const 错误
    const arr = [];
    arr.push(10, 20, 30);
    console.log(arr); // [10, 20, 30]
  </script>
</html>
  • 应用场景:声明对象类型使用const,非对象类型声明选择let

变量的解构赋值

  • ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值

    • 数组的解构赋值
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        const arr = ["张学友", "刘德华", "黎明", "郭富城"];
        // 数组的解构赋值 => 根据数组的下标有顺序的进行赋值
        let [zhang, liu, li, guo] = arr;
        console.log(zhang, liu, li, guo); // 张学友 刘德华 黎明 郭富城
      </script>
    </html>
    
    • 对象的解构赋值
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        // 对象的解构赋值
        const lin = {
            
            
          name: "林志颖",
          tags: ["车手", "歌手", "小旋风", "演员"],
          sayHi: function () {
            
            
            console.log("唱歌");
          },
        };
        // 对象的解构赋值是将对象中的各个属性取出来 变量名称必须与属性名称一致
        const {
            
             name, tags, sayHi } = lin;
        console.log(name, tags, sayHi); // 林志颖
        console.log(tags); // ['车手', '歌手', '小旋风', '演员']
        console.log(sayHi); // ƒ () {console.log("唱歌");}
        sayHi(); // 唱歌
      </script>
    </html>
    
    • 复杂解构
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        let wangfei = {
            
            
          name: "王菲",
          age: 18,
          songs: ["红豆", "流年", "暧昧", "传奇"],
          history: [{
            
             name: "窦唯" }, {
            
             name: "李亚鹏" }, {
            
             name: "谢霆锋" }],
        };
    
        const {
            
            
          name,
          age,
          // 数组的解构 => string,string,string,string
          songs: [one, two, three, four],
    
          // 数组的解构 => obj,obj,obj,obj
          history: [first, second, third],
        } = wangfei;
    
        console.log(name); // 王菲
        console.log(age); // 18
        console.log(one); // 红豆
        console.log(first); // {name: '窦唯'}
      </script>
    </html>
    
  • 注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式

模板字符串

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

    • 字符串中可以出现换行符
    • 可以使用${xxx}形式输出变量
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <ul></ul>
      </body>
      <script>
        const books = ["JavaScript", "Vue", "React", "Es6"];
        let str = "";
        for (let i = 0; i < books.length; i++) {
            
            
          str += `
          <li>${ 
              books[i]}</li>
        `;
        }
        // 获取 DOM 对象
        document.querySelector("ul").innerHTML = str;
      </script>
    </html>
    
  • 注意:当遇到字符串与变量拼接的情况使用模板字符串

简化对象写法

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

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        let name = "张三";
        let age = 20;
        const sayHi = function () {
            
            
          console.log("hi");
        };
    
        // 原始写法
        let obj = {
            
            
          // key:value 的写法
          name: name,
          age: age,
          sayHi: sayHi,
        };
        console.log(obj); // {name: '张三', age: 20, sayHi: ƒ}
    
        // 简化写法
        let newObj = {
            
            
          // 当key与value一致时,就可以只写一个就可以了
          name,
          age,
          sayHi,
        };
        console.log(newObj); // {name: '张三', age: 20, sayHi: ƒ}
    
        const person = {
            
            
          sayHi: function () {
            
            
            console.log(11);
          },
        };
        // 对象中的方法后 :function 是可以省略的
        const newPerson = {
            
            
          sayHi() {
            
            
            console.log(11);
          },
        };
      </script>
    </html>
    
  • 注意:对象简写形式简化了代码,所以以后用简写就对了

箭头函数

  • ES6允许使用「箭头」(=>)定义函数

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        // => 代替 function()
        const oldFn = function () {
            
            
          console.log("oldFn"); // oldFn
        };
        oldFn();
    
        const fn = () => {
            
            
          console.log("fn"); // fn
        };
        fn();
      </script>
    </html>
    
  • 箭头函数的注意点:

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

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // 箭头函数没有参数的情况
          const a = () => {
                
                
            console.log("没有参数的箭头函数");
          };
          a();
      
          // 箭头函数只有一个参数的情况(参数的括号可以省略)
          const b = (a) => {
                
                
            console.log("只有一个参数的箭头函数");
          };
          b();
      
          // 箭头函数的参数有多个时,不可以省略
          const c = (a, b) => {
                
                
            console.log(a, b); // 10 20
          };
          c(10, 20);
        </script>
      </html>
      

      在这里插入图片描述

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

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          // 代码函数只有一行,方法体的大括号可以省略
          const fo = () => console.log("代码函数只有一行,方法体的大括号可以省略");
          fo();
      
          // 代码行数只有一行,有返回值的情况,方法体的大括号和 return 可以省略的
          const sum = (a, b) => a + b;
          console.log(sum(10, 20));
        </script>
      </html>
      

      在这里插入图片描述

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

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          const obj = {
                
                
            name: "张三",
            age: 20,
            sayHi() {
                
                
              // this
              const _this = this;
              setTimeout(function () {
                
                
                // 计时器里面的 this 永远指向于 window
                console.log(`你好,${ 
                  _this.name}`);
              }, 2000);
            },
          };
          obj.sayHi();
      
          const obj2 = {
                
                
            name: "李四",
            age: 18,
            sayHi() {
                
                
              setTimeout(() => {
                
                
                // 箭头函数没有 this 指向,指向最近的 this
                // 这里受箭头函数的影响 this 指向 obj2
                console.log(`你好,${ 
                  this.name}`);
              }, 2000);
            },
          };
          obj2.sayHi();
        </script>
      </html>
      

      在这里插入图片描述

    • 箭头函数不能作为构造函数实例化

    • 不能使用arguments

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script>
          const fo = function () {
                
                
            console.log(arguments);
          };
          fo(1, 2, 3, 4);
      
          const foo = () => {
                
                
            // console.log(arguments); // 报错 arguments is not defined
          };
          foo(1, 2, 3);
        </script>
      </html>
      

      在这里插入图片描述

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

rest 参数

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

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        const bar = function () {
            
            
          console.log(arguments instanceof Array); // false
        };
        bar(10, 20, 30, 40, 50, 60);
    
        // 箭头函数 rest 参数
        // 使用 ... 将剩余没有接收的参数放在数组中
        const foo = (...args) => {
            
            
          console.log(args instanceof Array); // true
        };
        foo(10, 20, 30, 40, 50, 60);
    
        const fn = (a, b, ...args) => {
            
            
          console.log(a, b, args);
        };
        fn(10, 20, 30, 40, 50, 60);
      </script>
    </html>
    

    在这里插入图片描述

  • 注意:rest参数非常适合不定个数参数函数的场景

spread 扩展运算符

  • 扩展运算符(spread)也是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        // 展开数组
        let tfboys = ["德玛西亚之力", "德玛西亚之翼", "德玛西亚皇子"];
        function fn() {
            
            
          console.log(arguments);
        }
        fn(...tfboys);
    
        // 展开对象
        let skillOne = {
            
             q: "致命打击" };
        let skillTwo = {
            
             w: "勇气" };
        let skillThree = {
            
             e: "审判" };
        let skillFour = {
            
             r: "德玛西亚正义" };
        const gailun = {
            
             ...skillOne, ...skillTwo, ...skillThree, ...skillFour };
        console.log(gailun);
    
        // 数组的合并
        const a = [1, 2, 3, 4];
        const b = [5, 6, 7, 8];
        const c = a.concat(b);
        console.log(c); // [1, 2, 3, 4, 5, 6, 7, 8]
        const d = a.push(...b);
        console.log(d); // 8
    
        // 对象的合并
        const p1 = {
            
            
          name: "李四",
          age: 18,
        };
        const p2 = {
            
             ...p1, age: 30 }; // 在合并对象的时候 重复的属性会以最后一个出现的为准
        console.log(p2);
      </script>
    </html>
    

    在这里插入图片描述

迭代器

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

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

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

    • Array
    • Arguments
    • Set
    • Map
    • String
    • NodeListDOM节点)
  • 工作原理

    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
    • 每调用next方法返回一个包含valuedone属性的对象
    • 注: 需要自定义遍历数据的时候,要想到迭代器
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div>10</div>
      </body>
      <script>
        // const divs = document.querySelectorAll("div");
    
        // 获取到的 HTMLCollection 集合,没有办法 forEach
        const divs = document.getElementsByTagName("div");
        // divs.forEach((item) => {
            
            
        //   console.log(item); // 报错 divs.forEach is not a function
        // });
        for (const item of divs) {
            
            
          console.log(item); // 这个是可以遍历的
        }
    
        const objArr = [
          {
            
            
            name: "Vuejs",
            price: 18,
          },
          {
            
            
            name: "React",
            price: 10,
          },
          {
            
            
            name: "Angular",
            price: 28,
          },
        ];
        for (const item of objArr) {
            
            
          console.log(item);
        }
      </script>
    </html>
    

    在这里插入图片描述

Promise

  • PromiseES6引入的异步编程的新解决方案

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

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
    
      <body></body>
      <script>
        // 创建Promise的对象
        // 在创建Promise对象的时候,需要传入一个回调函数,
        // 这个回调函数会产生两个参数
        // 这两个参数是两个函数 resolve() 表示成功  reject() 失败
        const p = new Promise(function (resolve, reject) {
            
            
          setTimeout(() => {
            
            
            let a = 10;
            if (a == 10) {
            
            
              // 表示成功
              resolve(++a);
            } else {
            
            
              // 表示失败
              a = 20;
              reject(a);
            }
          }, 2000);
        });
    
        const p2 = new Promise((resolve, reject) => {
            
            
          // then表示成功
          // cath表示失败
          p.then((a) => {
            
            
            console.log(a); // 11
            if (a == 11) {
            
            
              resolve(++a);
            } else {
            
            
              reject(a);
            }
          }).catch((error) => {
            
            
            console.log(error);
          });
        });
    
        // p2.then(a=>{
            
            
        //   console.log(a);
        // })
    
        // p2.catch(error => {
            
            
        //   console.log(error);
        // })
      </script>
    </html>
    
  • Promise构造函数:Promise (excutor) {}

  • Promise.prototype.then方法

  • Promise.prototype.catch方法

  • Promise.prototype.all

Promise封装Ajax

  • Ajax

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    let xhr;
    // 创建XMLHttpRequest对象
    if (XmlHttpRequest) {
      
      
      xhr = new XMLHttpRequest();
    } else {
      
      
      xhr = new ActiveXObject("Microsoft.XML");
    }
    // 监听状态
    xhr.onreadystatechange = () => {
      
      
      // post 201
      // get 200
      if ((xhr.readyState == 4) & (xhr.status == 200) || xhr.status == 201) {
      
      
        // 处理操作
      }
    };
    // 开启连接
    xhr.open("get", "xxxx", true);
    xhr.send();
  </script>
</html>
  • Promise封装Ajax

    function $http(params) {
    
    
      const {
    
     method, url, body, header } = params;
      return new Promise((resolve, reject) => {
    
    
        let xhr;
        if (window.XMLHttpRequest) {
    
    
          xhr = new XMLHttpRequest();
        } else {
    
    
          xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xhr.onreadystatechange = () => {
    
    
          if (xhr.readyState == 4 && xhr.status == 200) {
    
    
            const {
    
     code, data } = JSON.parse(xhr.responseText);
            resolve(data);
          }
        };
        xhr.open(method, url);
        try {
    
    
          for (const key in header) {
    
    
            xhr.setRequestHeader(key, header[key]);
          }
        } catch (error) {
    
    
          console.log(error);
        }
        xhr.send(JSON.stringify(body));
      });
    }

Set

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

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
    
      <body></body>
      <script src="./http.js"></script>
      <script>
        let s1 = new Set();
        console.log(s1);
    
        // 成员的值都是唯一的 所以可以做数组的去重
        let s2 = new Set([22, 2, 22, 34, 34, 22, 5]);
        // 得到一个去重的对象
        console.log(s2); // {22, 2, 34, 5}
        let newArr = [...s2];
        console.log(newArr); // [22, 2, 34, 5]
      </script>
    </html>
    

    在这里插入图片描述

    • size返回集合的元素个数

    • add增加一个新元素,返回当前集合

    • delete删除元素,返回boolean

    • has检测集合中是否包含某个元素,返回boolean

    • clear清空集合,返回undefined

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
      
        <body></body>
        <script src="./http.js"></script>
        <script>
          // size 返回集合的元素个数
          let s2 = new Set([10, 20, 20, 30, 40, 30]);
          console.log("size:" + s2.size); // size:4
      
          // add 增加一个新元素,返回当前集合
          console.log(s2.add(5)); // {10, 20, 30, 40, 5}
      
          // delete 删除元素,返回 boolean 值
          // .delete(某一个元素)
          console.log(s2.delete(20)); // true
          console.log(s2); // {10, 30, 40, 5}
      
          // has 检测集合中是否包含某个元素,返回 boolean 值
          console.log(s2.has(10)); // true
      
          for (const iterator of s2) {
                
                
            console.log(iterator);
          }
      
          // clear 清空集合,返回 undefined
          console.log(s2.clear()); // undefined
        </script>
      </html>
      

      在这里插入图片描述

Map

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

    • size返回Map的元素个数
    • set增加一个新元素,返回当前Map
    • get返回键名对象的键值
    • has检测Map中是否包含某个元素,返回boolean
    • clear清空集合,返回undefined
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
    
      <body></body>
      <script src="./http.js"></script>
      <script>
        const map = new Map([
          ["name", "网星软件"],
          ["slogon", "不断提高行业标准"],
        ]);
        console.log(map); // {'name' => '网星软件', 'slogon' => '不断提高行业标准'}
    
        // size 返回 Map 的元素个数
        console.log(map.size); // 2
    
        // set 增加一个新元素,返回当前 Map
        console.log(map.set("old", 13));
    
        // get 返回键名对象的键值
        console.log(map.get("old")); // 13
    
        // has 检测 Map 中是否包含某个元素,返回 boolean 值
        console.log(map.has("name")); // true
    
        for (const item of map) {
            
            
          console.log(item);
        }
    
        // clear 清空集合,返回 undefined
        console.log(map.clear()); // undefined
      </script>
    </html>
    

    在这里插入图片描述

class

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

    • class声明类
    • constructor定义构造函数初始化
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
    
      <body></body>
      <script src="./http.js"></script>
      <script>
        // 创建类
        class Person {
            
            
          // 静态属性 可以直接被类名调用
          static type = "human";
    
          /**
           * 构造函数(构造方法) 不能写出箭头函数
           * 做初始化的
           */
          constructor(name, age) {
            
            
            this.name = name;
            this.age = age;
          }
    
          /**
           * 普通函数
           * 关于对象的行为操作
           */
          // sayHi() {
            
            
          //   console.log(`${this.name}:hi`);
          // }
          sayHi = () => {
            
            
            console.log(`${ 
              this.name}:hi`);
          };
    
          /**
           * 静态方法 被 static 修饰
           * 频繁使用的一些方法
           */
          static talk() {
            
            
            console.log("讲话");
          }
        }
    
        const person = new Person("张三", 18);
        console.log(person);
        person.sayHi();
    
        // 静态方法可以直接被类名调用 无需创建对象
        Person.talk();
        console.log(Person.type); // human
      </script>
    </html>
    

    在这里插入图片描述

    • extends继承父类
    • super调用父级构造方法
    • static定义静态方法和属性
    • 父类方法可以重写
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
    
      <body></body>
      <script src="./http.js"></script>
      <script>
        // 定义 Person 类
        class Person {
            
            
          constructor(name, age) {
            
            
            this.name = name;
            this.age = age;
          }
          sayHi = () => {
            
            
            console.log(`${ 
              this.name}:hi`);
          };
          static talk() {
            
            
            console.log("讲话");
          }
        }
    
        // 定义 Student 类,并继承 Person,只能继承一个
        class Student extends Person {
            
            
          constructor(name, age, score) {
            
            
            // 交给父类
            super(name, age);
            // 自己的参数
            this.score = score;
          }
          // 子类可以重写父类中的方法
          sayHi = () => {
            
            
            console.log("hello");
          };
          static talk() {
            
            
            console.log("spack");
          }
        }
    
        const stu = new Student("张三", 18, 66);
        console.log(stu);
        stu.sayHi();
        Student.talk();
      </script>
    </html>
    

    在这里插入图片描述

没有模块化产生的问题

  • 结构目录

    在这里插入图片描述

  • 代码展示

    • bar.js

      var a = true;
      
    • foo.js

      var a = false;
      
    • index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script src="./bar.js"></script>
        <script src="./foo.js"></script>
        <script>
          if (a) {
                
                
            // 没有内容打印 前面的var a把后面的var a给覆盖了,导致最后执行了foo.js里面的var a = false
            // 但是当你把 俩个文件引入的顺序换一下就会打印出来
            // 当你把这俩个文件看成俩个不同的人写的项目,这样就会造成项目之间的互相影响 也会使后期的代码不好维护
            console.log("a == true");
          }
        </script>
      </html>
      
  • 早期解决的办法:(闭包)

    • bar.js

      var bar = (function () {
        // 返回一个对象 这样我们就可以使用 对象.属性 的方式获取
        return {
          a: true,
        };
      })();
      
    • foo.js

      var foo = (function () {
        // 返回一个对象 这样我们就可以使用 对象.属性 的方式获取
        return {
          a: false,
        };
      })();
      
    • index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body></body>
        <script src="./bar.js"></script>
        <script src="./foo.js"></script>
        <script>
          if (bar.a) {
                
                
            console.log("a == true"); // a == true
          }
        </script>
      </html>
      
    • 这样虽然可以解决问题,但是当你一直在bar.jsfoo.jsreturn里面写代码,会发现非常臃肿。所以让我们看看下面ES6中的模块化。

模块化

  • 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
  • 模块化的优势有以下几点:
    • 防止命名冲突
    • 代码复用
    • 高维护性
    • 2.18.2.模块化规范产品
    • ES6之前的模块化规范有:
      • CommonJS=> NodeJS、Browserify
      • AMD => requireJS
      • CMD => seaJS

ES6 模块化语法

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

  • export命令用于规定模块的对外接口

    • export导出 将需要给别人使用的变量或者方法暴露出去
  • import命令用于输入其他模块提供的功能

    • import导入 将别人导出的变量和方法引入使用
  • 导出导入的方式(输出打印需要开启一个服务)

    • 目录结构

      在这里插入图片描述

    • 单独导出

      • foo.js

        export const a = 10;
        
      • main,js

        // 程序的入口(主文件)
        
        // 导入方式一
        import * as foo from "./foo.js";
        console.log(foo.a); // 10
        
        // 程序的入口(主文件)
        
        // 导入方式二
        import {
                  
                   a } from "./foo.js";
        console.log(a); // 10
        
      • index,html

        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Document</title>
          </head>
          <body></body>
          <script src="./main.js" type="module"></script>
        </html>
        
    • 统一导出

      • bar,js

        const name = "张三";
        
        const sum = function (a, b) {
                  
                  
          return a + b;
        };
        
        // 导出
        export {
                  
                   name, sum };
        
      • foo.js

        const a = 10;
        
        const sum = (a, b) => console.log(a + b); // 30
        
        export {
                  
                   a, sum };
        
      • main.js

        // 程序的入口(主文件)
        
        import * as bar from "./bar.js";
        import * as foo from "./foo.js";
        
        console.log(bar.name); // 张三
        console.log(bar.sum(10, 30)); // 40
        console.log(foo.a); // 10
        foo.sum(10, 20);
        
      • index,html

        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Document</title>
          </head>
          <body></body>
          <script src="./main.js" type="module"></script>
        </html>
        
    • 默认导出(一个)

      • bar,js

        export default 10;
        
      • foo,js

        // 这里 a 前面不能加 const
        // 这里默认导出只能有一个 不可以写多个默认导出
        
        export default () => 10 + 20;
        
      • main,js

        // 程序的入口(主文件)
        
        import bar from "./bar.js";
        import foo from "./foo.js";
        
        console.log(bar); // 10
        console.log(foo()); // 30
        
      • index,html

        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Document</title>
          </head>
          <body></body>
          <script src="./main.js" type="module"></script>
        </html>
        
    • 默认导出(多个)

      • foo.js

        const a = 10;
        const sum = () => 10 + 20;
        export default {
                  
                   a, sum };
        
      • main,js

        // 程序的入口(主文件)
        
        import foo from "./foo.js";
        
        console.log(foo.a); // 10
        console.log(foo.sum()); // 30
        
      • index,js

        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Document</title>
          </head>
          <body></body>
          <script src="./main.js" type="module"></script>
        </html>
        

ES10 新增的模块化

  • 目录结构

    在这里插入图片描述

  • 代码展示

    • data.js

      export const formatDate = () => new Date();
      
    • math.js

      export const radom = () => Math.random();
      
    • index.js

      // 统一导出
      // * 表示所有
      
      export * from "./data.js";
      export * from "./math.js";
      
    • main.js

      import {
              
               formatDate, radom } from "./index.js";
      
      console.log(formatDate());
      console.log(radom());
      
    • index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body>
          <script src="./main.js" type="module"></script>
        </body>
      </html>
      

      在这里插入图片描述

asyncawait

  • asyncawait两种语法结合可以让异步代码像同步代码一样
  • async函数的返回值为promise对象
  • promise对象的结果由async函数执行的返回值决定
  • await必须写在async函数中
  • await右侧的表达式一般为promise对象
  • await返回的是promise成功的值
  • awaitpromise失败了, 就会抛出异常, 需要通过try...catch捕获处理

Rest/Spread 属性

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

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body></body>
      <script>
        function connect({
             
              host, port, ...user }) {
            
            
          console.log(host, port); // 127.0.0.1 8080
          console.log(user); // {username: 'admin', password: '123456', type: 'master'}
        }
        connect({
            
            
          username: "admin",
          password: "123456",
          host: "127.0.0.1",
          port: 8080,
          type: "master",
        });
      </script>
    </html>
    

    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/HTML_Z/article/details/124436191