ES6新特性学习02

一、ES6新特性

  1. ES6-Peomise基本使用

    • Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并获取其成功或失败的结果。
      • Promise 构造函数:Promise(excutor){}
      • Promise.prototype.then方法
      • Promise.prototype.catch方法
    • 使用Promise的一般步骤
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
              //实例化Promise对象
      const p=new Promise(function(resolve,reject){
      setTimeout(function(){
      // let data="数据库中的数据";
      // resolve(data); //成功时调用resolve()
      let err="数据读取失败";
      reject(err);
      },1000);
      });
      //调用Promise中的then方法
      p.then(function(value){
      console.log(value)
      },function(reason){
      console.log(reason);
      })
    • 使用Peomise发送ajax请求
    • Promise.prototype.then方法
      • then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
      • 如果回调函数中返回的结果是非 Promise类型的属性,状态为成功,返回值为对象的成功值
      • 如果回调函数返回的结果是 Promise对象,状态取决于Peomise返回的状态,值为Promise返回值
      • 如果回调函数抛出错误,状态也为失败,返回值就是抛出值
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
              const res=p.then(value=>{
        //返回非Promise类型,p为true;
        // return "111"

        // 是Promise对象
        //return new Promise((resolve,reject)=>{
        // resolve("成功")
        // })

        // 抛出错误,状态也是错误
        throw "出错了!";
        },reason=>{
        console.log("错误信息")
        })
        console.log(res)
    • Promise的then方法实现链式调用,异步请求,避免回调地狱
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
            //实例化Promise对象
      new Promise(function(resolve,reject){
      setTimeout(function(){
      let data=20;
      resolve(data); //成功时调用resolve()
      },1000);
      }).then(value=>{
      return new Promise(function(resolve,reject){
      resolve(value+2);
      })
      }).then(value=>{
      console.log(value+2);
      })
    • Promise.prototype.catch方法
      1
      2
      3
      p.catch(function(reason){
      console.error(reason);
      })
  2. ES6-新的数据结构set

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

    • 集合的属性和方法

      • size 返回集合的元素个数
      • add 增加一个新元素,返回当前集合
      • delete 删除元素,返回Boolean值
      • has 检测集合中包含某个元素,返回Boolean值
      • clear 清空集合里面的所有元素
        1
        2
        3
        4
        5
        6
        7
        8
             let s=new Set(['张三','李四','王五','张三','小华']);
        //去重输出
        console.log(s);
        //输出集合元素个数
        console.log(s.size);
        // 向集合中添加新元素
        s.add("小红");
        console.log(s);
    • 集合实际操作

      • 实现数组去重

        1
        2
        3
        4
              let arr=[1,2,3,4,5,6,3,2,1,2,3];
        //数组去重
        let result=[...new Set(arr)];
        console.log(result); //输出[1,2,3,4,5,6]
      • 实现两个数组交集运算

        1
        2
        3
        4
        5
        6
        7
        8
              // 交集
        let arr=[1,2,3,4,5,6,3,2,1,2,3];
        let arr2=[4,2,4,3,2];
        let res=new Set(arr2); //数组arr2去重类型为集合
        let result=[...new Set(arr)].filter(item=>{
        return res.has(item);
        })
        console.log(result); //输出[2,3,4]
      • 实现两个数组并集运算

        1
        2
        3
        4
        5
              //并集
        let arr=[1,2,3,4,5,6,3,2,1,2,3];
        let arr2=[4,2,4,3,2,9,8];
        let result=[...new Set([...arr,...arr2])];
        console.log(result); //输出[1,2,3,4,5,6,9,8]
      • 实现两个数组差集运算

        1
        2
        3
        4
        5
        6
        7
        8
              // 差集(arr对arr2求差集)
        let arr=[1,2,3,4,5,6,3,2,1,2,3];
        let arr2=[4,2,4,3,2];
        let res=new Set(arr2); //数组arr2去重类型为集合
        let result=[...new Set(arr)].filter(item=>{
        return !res.has(item);
        })
        console.log(result);
  3. ES6-新的数据结构Map

    • ES6提供了Map数据结构,它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用[扩展运算符]和[for…of]进行遍历。
    • Map的属性和方法
      • size 返回Map的元素个数
      • set 增加一个新元素,返回当前Map
      • get 返回键名对应的键值
      • has 检测集合中包含某个元素,返回Boolean值
      • clear 清空Map里面的所有元素,返回undefined
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
             //声明Map
        let m=new Map();
        //新增元素
        m.set('name','fanda');
        m.set('change',function(){
        console.log("这是一个函数")
        })
        let key={
        cityt:"北京"
        }
        m.set(key,["上海","广东","深圳"]);
        //删除元素
        m.delete('change');
        console.log(m);
        //遍历Map
        for(let v of m){
        console.log(v);
        }
  4. Class类

    • 引入class(类)这个概念,作为对象模板。通过class关键之字,可以定义类。基本上,ES6的class类可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只有让对象原型的写法更加清晰、更像面向对象编程的语法而已。
    • 知识点
      • class 声明类
      • constructor 定义构造函数初始化
      • extends 继承父类
      • super 调用父级构造方法
      • static 定义静态方法和属性
      • 父类方法可以重写
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
                   //ES5构造函数的方法
        function phone(brand,price){
        this.brand=brand;
        this.price=price;
        }
        //添加方法
        phone.prototype.call=function(){
        console.log("可以用来打电话");
        }
        //实例化对象
        let huawei=new phone("华为",5699);
        console.log(huawei);


        class phone{
        //构造函数,名字不能修改
        constructor(brand,price) {
        this.brand=brand;
        this.price=price;
        }
        //方法名必须使用该语法,不能使用ES5的对象完整模式
        call(){
        console.log("手机可以用来打电话!")
        }
        }
        //实例化对象
        let xiaomi=new phone("mi",2699);
        console.log(xiaomi);
    • class静态成员
      • 实例对象不具备构造函数对象的属性和方法,实例对象的属性和构造函数原型对象是相通的。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
              function phone(){
        }
        phone.name="手机";
        phone.prototype.user="root"; //原型对象
        phone.change=function(){
        console.log("可以用来打电话")
        }
        let nkia=new phone();
        console.log(phone.name); //输出 "手机"
        console.log(nkia.name); //输出undefined
        console.log(nkia.user); // 输出root
      • 对于static标志的方法,它属于类而不属于实例对象。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
               class phone{
        //静态属性
        static name="手机";
        static change(){
        console.log("可以用来打电话")
        }
        }
        let nokia=new phone();
        console.log(phone.name); //输出 "手机"
        console.log(nokia.name); //输出undefined
    • ES5使用构造函数实现继承
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
              // 手机父级
      function phone(brand,price){
      this.brand=brand;
      this.price=price;
      }
      phone.prototype.call=function(){
      console.log("可以用来打电话!")
      }
      //智能手机
      function SmartPhone(brand,price,color,size){
      phone.call(this,brand,price);
      this.color=color;
      this.size=size;
      }
      //设置子集构造函数的原型
      SmartPhone.prototype=new phone;
      SmartPhone.prototype.constructor=SmartPhone;
      //声明子类的方法
      SmartPhone.prototype.photo=function(){
      console.log("可以用来拍照")
      }
      //实例化
      const chuizi=new SmartPhone('锤子',3322,'黑色','5.5英寸');
      console.log(chuizi);
      chuizi.photo();
    • ES6中的类继承
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
             //父类
      class phone{
      constructor(brand,price) {
      this.brand=brand;
      this.price=price;
      }
      change(){
      console.log("我可以打电话");
      }
      }
      //继承父类extends
      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("我可以用来打游戏");
      }
      }
      // 实例化对象
      const meizu=new SmartPhone("魅族",1999,"白色","6.2inch");
      console.log(meizu);
      meizu.photo(); //调用自己的方法
      meizu.change(); //调用继承自父类的方法
    • 子类对父类方法的重写
      • js的类中,子类是不能直接调用父类的同名方法的
      • 方法的重写就是在子类中声明一个和父类的同名方法进行重写
    • getter和setter设置
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
             class phone{
      get price(){
      console.log("价格属性被读取");
      return "price:100"
      }
      set price(val){
      console.log("价格属性被设置"+val)
      }
      }
      let s=new phone();
      s.price=199; //调用set
      console.log(s.price); //调用get
  5. ES6扩展数值

    • Number.EPSILON是JavaScript表示的最小精度
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
            //1.Number.EPSILON
      function equal(a,b){
      if(Math.abs(a-b)<Number.EPSILON)
      {
      return true;
      }
      else{
      return false;
      }
      }
      console.log(equal(0.1+0.2,0.3));
    • 二进制和八进制。二进制0b,八进制0o
    • Number.inFinite 检测一个数值是否为有限数
    • Number.isNaN 检测一个数的数值是否为NaN
    • Number.parseInt字符串转为整数,Number.ParseFlot 字符串转为浮点数。
    • Number.isInteger 判断一个数是否为整数
    • Math.trunc 将数字的小数部分抹去
    • Math.sign 判断一个数到底为正数,负数 还是零
  6. ES6对象方法扩展

    • Object.is 判断两个值是否完全相等。
      1
      2
      3
            console.log(Object.is(11,11));  //输出true
      console.log(Object.is(NaN,NaN)); //输出true
      console.log(NaN===NaN); //输出false
    • Object.assign 对象的合并
      1
      2
      3
            console.log(Object.is(11,11));  //输出true
      console.log(Object.is(NaN,NaN)); //输出true
      console.log(NaN===NaN); //输出false
    • Object.setPrototypeOf设置原型对象 和 Object.getPrototypeOf
      1
      2
      3
      4
      5
      6
      7
      8
            const school={
      name:"xhu"
      }
      const cities={
      city:["北京","上海","广东","深圳"]
      }
      Object.setPrototypeOf(school,cities);
      console.log(school);
  7. ES6模块化

    • 模块化是指将一大堆程序文件拆分成许多小的文件,让后将小文件组合起来。
    • 模块化的好处:
      • 防止命名冲突
      • 代码复用
      • 高效维护
    • 模块化规范产品,ES6之前的模块化规范有:
      • CommonJs => NodeJs、Browserify
      • AMD => requireJs
      • CMD => seaJs
    • ES6 模块化语法
      • 模块功能主要由两个命令构成:export和import
      • export 命令用于规定模块的对外接口。
      • import 命令用于输入其他模块提供的功能。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
           // m1.js
        export let user ="fanda";
        export function fn(a, b) {
        return a + b;
        }

        //在其他文件引入
        <script type="module">
        import * as m1 from "./js/m1.js"
        console.log(m1);
        </script>
    • ES6暴露数据语法汇总
      • 分别暴露
        1
        2
        3
        4
        5
        // m1.js
        export let user ="fanda";
        export function fn(a, b) {
        return a + b;
        }
      • 统一暴露
        1
        2
        3
        4
        5
        6
        let user ="fanda";
        function fn(a, b) {
        return a + b;
        }
        //统一暴露
        export {user,fn};
      • 默认暴露,注意在引入使用时为m3.default.user
        1
        2
        3
        4
        5
        6
        7
          //默认暴露m3.js
        export default{
        user:"fanda",
        change:function(){
        console.log("默认暴露方法")
        }
        }
    • ES6引入模块语法汇总
      • 通用导入方式
        1
        import * as m1 from "./js/m1.js"
      • 解构赋值形式(应对分别暴露)
        1
        2
        3
        4
        5
         import {user,fn} from "./js/m2.js"
        //重名后使用别名
        import {user as newuser,fn} from "./js/m1.js"
        // 暴露默认暴露模块,必须进行别名
        import {default as m3} from "./js/m3.js"
      • 简便形式,针对于默认暴露
        1
        2
        import  m3 from "./js/m3.js"
        console.log(m3.user); // 不用加 default
    • 浏览器使用ES6模块的方式二(针对于需要引入大量文件)
      • 首先新建一个Js文件
        1
        2
        3
        4
        // app.js
        import * as m1 from "./js/m1.js"
        import * as m2 from "./js/m2.js"
        import * as m3 from "./js/m3.js"
      • 然后利用script标签引入使用
        1
        <script src="./js/app.js" type="module"></script>
    • Babel对ES6模块化代码转换
      • Babel官网:https://www.babeljs.cn/
      • 使用babel将Js比较新的语法转化为浏览器能够识别的ES5语法
      • (1)安装工具babel-cli , babel-preset-env , browserify(webpack)
      • (2)通过 npx babel js(js文件位置) -d dist/js --presets-label-preset-env
      • (3)打包 npx browserify dist/js/app.js -o dist/bundle.js