ES6学习(三)

一.
   Set类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构展。Set 构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
    1)特性:
      不允许重复值出现

      应用:数组去重
      Array.form(new Set(arr))
    2)API
      Set.prototype.size        返回Set实例的成员总数。
      Set.prototype.add(value)    添加某个值,返回Set结构本身
      Set.prototype.delete(value)    删除某个值,返回一个布尔值,表示删除是否成功。
      Set.prototype.has(value)    返回一个布尔值,表示该值是否为Set的成员。
      Set.prototype.clear()    清除所有成员,没有返回值。
      Set.prototype.keys()    返回键名的遍历器
      Set.prototype.values()    返回键值的遍历器
      Set.prototype.entries()    返回键值对的遍历器
      Set.prototype.forEach()    使用回调函数遍历每个成员
 

let arr =[1,2,3,4,4,5,5,3,2,1,7]
//创建Set集合 成员是唯一的,key-value是一样的
let set =new Set(arr)
set.add(100)
//console.log(Array.from(set));
console.log(set.size);
// 删除元素
console.log(set.delete(1));
//判断有没有某个成员
console.log(set.has(1));返回布尔值true或者false
//set.clear();

// 遍历
let keys= set.keys()
let values= set.values()
let entries= set.entries()

console.log(entries.next());

set.forEach((value)=>{
    console.log(value);
})

  4.Map集合
    类似于对象,key-value对应的集合。
    1)特点:
      key值不局限于字符串,可以是任意数据类型
    2)API
      Map.prototype.size    返回 Map 结构的成员总数。
      Map.prototype.set(key, value)    set方法设置键名key对应的键值为value,然后返回整个map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
      Map.prototype.get(key)    get方法读取key对应的键值,如果找不到key,返回undefined。
      Map.prototype.has(key)    has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
      Map.prototype.delete(key)delete方法删除某个键,返回true。如果删除失败,返回false。
      Map.prototype.clear()    清除所有成员,没有返回值
      Map.prototype.keys()    返回键名的遍历器
      Map.prototype.values()    返回键值的遍历器
      Map.prototype.entries()    返回键值对的遍历器
      Map.prototype.forEach()    使用回调函数遍历每个成员

let obj1={
    name:'zs',
    age:12,
    gender:'male'
}
let map =new Map(Object.entries(obj1));
// 添加元素
map.set(true,0);
map.set({a:1,b:2},['tom','jacky']);
console.log(map.size);
console.log(map.get(true));
console.log(map);
map.forEach((value,key)=>{
    console.log(value,key)
})

二.class类
    1)介绍
      ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。
      通过class关键字,可以定义类。ES6 的class可以看作是构造函数一个语法糖
      语法糖:具有特殊功能的代码写法,内部封装了一些方法,让一些复杂代码的编写及其用法变得简单
    2)构造器
      constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
      一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
      class Person{
        constructor(name,age){
          this.name = name;
          this.age = age;
        }
      }
    3)实例方法、属性
      定义在类体中的方法称为实例方法。如下,sayName方法就是实例方法,
      本质上该方法应该是声明在Person.prototype中,可供所有的实例调用,因此称为实例方法。
      class Person{
        constructor(name,age){
          this.name = name;
          this.age = age;
        }
        sayName(){
          console.log("i am ",this.name);
        }
      }
    4)静态方法、属性
      通过static关键字来定义静态属性和静态方法。
      静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。
      在静态方法中,this指向当前类【构造函数】
      class Person{
        static num = 200;
        static number(){
          return this.num;
        }
      }
      console.log(Person.number());    //200

    5)继承
            ES5 如何继承
        实例使用属性和方法
        1.从实例对象本身查找属性或者方法
        2.如果实例没有,从构造函数的原型对象中找
        3.如果还没有,从父构造函数的原型对象中找
        function Person(){}
        Person.prototype={};
        var p1=new Person();
        p1.sayName=function(){};
        p1.sayName();
        //p1去调用sayName,自身有访问自身,自身没有访问构造函数原型对象,
        构造函数原型对象没有去找父构造函数
        1.经典继承
        function Animal(type,age,weight,length){
            this.type=type;
            this.age=age;
            this.weight=weight;
            this.length=length
        }
        Animal.prototype={
            constructor:Animal,
            sayType:function(){
                console.log(this.type)
            }
        }

        function Dog(type,age,weight,length,name,color){
                // 经典继承又称为构造函数继承
                Animal.call(this,type,age,weight,length);
                this.name=name;
                this.color=color;
        }
        处理完构造函数处理原型对象

2.原型链继承
        子构造函数的原型指向父构造函数的原型对象
        Dog.prototype=new Animal();
        Dog.prototype.constructor=Dog;
        Dog.prototype.sayColor=function(){
            console.log(this.color)
        }
        var d1=new Dog('狗',1,'10kg','40cm','可乐','白色');
        console.log(d1);
        d1.sayType();
        d1.sayColor();
      ES5继承
        借用构造函数继承
          function Animal() {}
          function Dog() {
            Animal.call(this)
          }
        原型链继承
          子构造函数的原型指向父构造函数的实例
          Dog.prototype = new Anmimal()
          Dog.prototype = Anmimal.prototype
      ES6继承
        用法
          class Dog extends Anmimal {
            constructor(name,age,weight) {
              super(name,age);
            }
          }
          let dog = new Dog('二狗',1,'10KG')
        子类继承父类(构造函数继承,继承静态方法、属性)
          子类的构造函数继承父类的构造函数
          子类构造函数的原型对象指向父类构造函数
          Dog.__proto__ === Animal
        子类原型对象继承父类原型对象(方法继承,继承实例方法、属性)
          Dog.prototype.__proto__ === Animal.prototype
          dog.__proto__.__proto__ === Animal.prototype
  2.Symbol
    1)介绍
      ES6 引入的一种新的原始数据类型Symbol,表示独一无二的值。
      Symbol函数可以接受参数,表示对于这个唯一值的描述。
    2)使用
      Symbol()函数会返回symbol类型(基本数据类型)的值
        let s = Symbol()
        typeof s ;    //’symbol’
        symbol类型的值是独一无二的
      在对象中使用symbol
        用于对象的属性名,就能保证不会出现同名的属性。
        这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖
        let sy1 = Symbol();
        obj[sy1] = 'hello'
        let obj2 = {
          ...obj1,
          // key为变量时,需要用[]包裹
          [sy1]: 'world'
        }
    3)Symbol.for(key)
      和 Symbol()不同的是,用Symbol.for()方法创建的symbol会被放入一个全局symbol注册表中。
      并不是每次都会创建一个新的symbol,它会首先检查给定的 key 是否已经在注册表中了。
      假如是,则会直接返回上次存储的那个。否则,它会再新建一个。
      比如:调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。
      如果想要用同一个变量,可以使用Symbol.for('name')注册一个全局的,下次如果要获取该symbol值,则再次Symbol.for('name')

    4)Symbol.keyFor(sy1)  
      检测symbol值是否在全局登记过,返回key或者undefined。
      返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。

    5)应用:消除魔术字符串:
  魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
      风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。


消除魔术字符串:

let shapes = {
    SJX: Symbol('三角形'),
    JX: Symbol('矩形'),
    YX: Symbol('圆形')
  }
  
  function computedArea (shape, options) {
    let result = 0
    switch (shape) {
      case shapes.SJX:
        result = .5 * options.width * options.height
        break;
      case shapes.JX:
        result = options.width * options.height
        break;
      case shapes.YX:
        result = Math.PI * options.r * options.r
        break;
      default:
        result = -1
        break;
    }
    return result
  }
  
  let result = computedArea(shapes.SJX, { width: 10, height: 20 })
  console.log(result);

三.

es5处理异步 回调函数

 1.Promise
    Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。
    它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
    Promise对象,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
    Promise对象提供统一的接口,使得控制异步操作更加容易。
    1)创建Promise实例
      // 实例化
      Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,它们是两个函数
      Promise对象代表一个异步操作有三种状态: pending(进行中)、fulfilled(已成功)和rejected(已失败)。
      状态发生改变之后就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)
      let promise = new Promise((resolve, reject) => {
        if(1 > 0) {
          // pending => fulfilled
          resolve('success');
        } else {
          // pending => rejected
          reject('error')
        }
      })
      // 访问promise实例内部的状态
      promise.then(res => {
        console.log(res)
      }).catch(error => {
        console.error(error)
      })
    2)实例方法
      .then()
        // promise状态为fulfilled
        参数:函数,函数内部的参数是resolve传过来的实参
      .catch()
        // promise状态为rejected
        参数:函数,函数内部的参数是reject传过来的实参
      .finally()
        无论promise状态是成功还是失败,都会执行里面的代码
    3)静态方法
      Promise.all([pro1,pro2])
        将pro1和pro2包装成数组作为实参传递进去
        返回值:promise对象。结果 =》pro1,pro2都成功才成功,有一个失败就失败
      Promise.race([pro1,pro2])
        将pro1和pro2包装成数组作为实参传递进去
        返回值:promise对象。结果 =》pro1,pro2谁先回来就用谁都结果(无论成功或者失败)
      Promise.any([pro1,pro2])
        将pro1和pro2包装成数组作为实参传递进去
        返回值:promise对象。结果 =》pro1,pro2都失败才失败,有一个成功就成功
      Promise.resolve()
        参数:任意
        返回值:状态为fulfilled的promise对象
      Promise.reject()
        参数:任意
        返回值:状态为rejected的promise对象
  2.Generator
    是ES6的异步编程解决方案
    类似于状态机,内部封装了多个状态
    返回值:迭代器对象
    通过调用.next()方法,访问迭代器对象内部的状态

    使用:
      function* genFun() {
        let result = yield 'one'

        console.log(result); // hello
        yield 'two'

        retrun 'others'
      }
      let gen = genFun(); // gen是generator函数返回的迭代器对象
      gen.next();
      gen.next('hello')
 async函数是generator函数的语法糖
    是ES6的异步编程解决方案
    关键字
      function关键字前加上 async(异步)
      异步请求之前,加上 await(等待)
    使用
      async function findAll() {
        let result = await $.get('......');
        console.table(result.data)
      }

上一篇:JS原型与原型链


下一篇:instanceof运算符的实质:Java继承链与JavaScript原型链