ES6

108 阅读4分钟

ECMAScript6

语法标准: 开发者 执行者(nodejs / 浏览器)

  1. hello world
    1. 安装nodejs
    2. 查看版本

    node --version

    1. 第一个程序
    1. nodejs交互界面
    2. 编写代码,执行 vihello.jsvi hello.js node hello.js 二、 注释
    // /**/

三、 变量声明

  弱类型
  var 奇葩(其他语言)
    1. 重复声明
      var a;
      var a;
    2. 变量的提升
      console.log(d);
      var d;
    3. 没有局部作用域
      function foo(){
        var result = 0;
        for(var i=0;i<=100;i++){
          result += i;
        }
        console.log(result)
        console.log(i);
      }
  let 
    1. 不可重复声明
    2. 不存在变量提升
    3. 具有局部作用域
  const 
    常量,只能赋值一次的变量,其他与let保持相同特性
    let a = 3;
    a++;  // 4
    const b = 3;
    b++;  //error

    const obj = {age:1}
    obj.age++;  // age 2

四、 解构

  使用模式匹配方式从一个对象、数组中快速获取值的方式
  let obj = {
    name:"terry",
    age:12,
    gender:"male",
    telephone:"18812344321",
    email:"licy@briup.com"
  }
  let a = obj.name;
  let b = obj.age;
  let c = obj.gender;
  1. 对象解构
    let {
      name:name,
      age:age
    } = {
      name:"terry",
      age:12,
      gender:"male",
      telephone:"18812344321",
      email:"licy@briup.com"
    }
    let {name,age,gender} = {name:"terry",age:12}
    let {name,age,gender='男'} = {name:"terry",age:12}

    let {toString} = 2;
    let {push} = [1,2,3]
    // 自动装箱 let n = new Number(2)
    let n = 2;
    toString.call(n)  '2'
    n.toString();   '2'
  2. 数组解构
    let [a,b,c] = ['terry','tom','jacky']
    let [a,b,c,d] = ['terry','tom','jacky']
    let [a,b,c,d='vicky'] = ['terry','tom','jacky']

五、 字符串拓展 String

  1. 可迭代的对象
  2. API拓展 lodash
    1) 静态方法(声明在构造函数)
    2) 实例(成员)方法(声明在原型对象中)
    
  Number扩展
  Number.isNaN
  Number.isInfinite
  Number.parsetInt
  Number.parsetFloat
  Number.isInteger
  
 对象 Object
  1. 对象简写
    let name = "terry"
    let obj = {name}
    function foo(){}
    let obj = {
      name:"terry",
      foo,
      sayName(){

      }
    }

    let url = "/article/deleteById"
    let id = 1;
    $.get(url,{id})
  2. 扩展运算符
    let {name,...other} = {name:"",a:"",b:""}

    let p1 = { page: 2, pageSize: 10 }
    let p2 = { title: '新冠'}

    Object.assgin(p1,p2)


    let param = { 
      page: 2, 
      pageSize: 10 ,
      title: '新冠'
    }
    param = {
      ...param,
      page:3
    }
    param = Object.assgin({},param)
    监控param的改变?

    param 参数 
  3. API
    Object.is()
    Object.assign()  
    Object.keys(obj)       键的数组
    Object.values(obj)     值的数组
    Object.entries(obj);   键值对组成的数组的数组
    Object.setPrototypeOf(obj,prototype)
    Object.getPrototypeOf(obj)
    让类数组可以调用所有的数组方法?

六、 原型

  每个函数都有一个原型对象与之对应,函数中有个指针
  prototype指向这个原型,原型中有个指针constructor指向函数

  一个函数的特性与其调用方式有关,如果通过new来调用,这个函数可以理解为构造函数;如果通过()、apply、call来调用,这个函数可以理解为普通函数

  function Student(name,age){
    this.name = name;
    this.age = age;
  }
  new Number()  创建数值的实例对象
  Number()      将其他数据类型转换为Number

  let arr = new Array()
  arr instanceof Object

七、数组 Array

  静态
    Array.from()
      将类数组对象、set转换为数组
    Array.of()
      将参数放置到数组内并且返回
  非静态
    Array.prototype.keys
    Array.prototype.values
    Array.prototype.entries
    Array.prototype.includes()
    Array.prototype.flat(Infinity)

    这三个方法返回值为迭代器对象
      迭代器对象的调用:
        1. for-of
        2. iterator.next()
        3. 拓展运算符

八、函数拓展

  1) 默认值
  2) rest参数
    扩展运算符的逆运算
    let arr = [1,2,3]
    let n = [9,8,7,...arr]
    let [a,...b] = [1,2,3,4,5]

    function foo(a,...b){
      console.log(a);
      console.log(b);
    }

九、 Promise 对异步操作进行封装。 状态:待定、成功、失败

  1) 构造函数
    let p = new Promise((resolve,reject)=>{
      
    })

  2) 静态方法
    Promise.xxx

  3) 实例方法
    Promise.prototype.xxx

  ajax  
    GET /carousel/findAll HTTP/1.1
    Authorization:XXWEREAWFEWAFAEW

十、 Symbol

  函数,无法使用new来调用,每次执行都可以产生式一个唯一的值(基本数据类型),这个值用来作为属性名。
  let s1 = Symbol()
  let s2 = "name"
  let obj = {
    [s1]:"terry",    // 神秘的唯一值:"terry"
    [s2]:"tom" ,     // name:"terry"
    s3:"jacky"       // s3 :"jacky"
  }
  obj[s1]
  obj.name
  obj.s3
  1. Symbol() 函数
    用来产生唯一值
  2. Symbol(flag) 
    flag字符串,表示标识
  3. Symbol.for(flag)
  4. Object.getOwnPropertySymbols()
    可以获取某个对象中所有的symbol属性名
  5. 系统内置Symbol
    1) Symbol.hasInstance
      所有的构造函数都内置这么个方法,当instanceof的时候会调用
      let obj = {
        [ Symbol.hasInstance]:function(o){
          return false
        }
      }
      let o = {}
      {} instanceof obj;
    2) Symbol.iterator
      当迭代对象的时候会被调用 for-of
      for(let o of arr){}

十一、 集合

  是对数组和对象的拓展
  1. Set
    不可以存放相同的值,不可以通过索引来访问。Set是一种特殊的map
    let arr = [1,2,3,4,5,1,2,3]
    let arr = ['terry','larry']
    1) 构造函数
      new Set()
    2) 原型
      Set.prototype.size
      Set.prototype.add()
      Set.prototype.delete()
      Set.prototype.clear()
      Set.prototype.keys()
      Set.prototype.values()
      Set.prototype.entries()
      Set.prototype.forEach()
  2. Map
    键值对,键可以为任意数据类型;
    Map可以提供额外的api

    购物车(家政)
      goods 
        id    name    price
        fbm = {1   北京方便面  2}
        kqs = {2   怡宝矿泉水  2.5}
      let shopcar = new Map();
      shopcar.set(1,1)
      shopcar.set(2,3)

    如何将一个对象转换为map?
    1) 构造函数
      let map = new Map([[],[]])

    2) 原型方法

十二、 代理

  1. 对象 setter/getter
    let obj = {}    // 目标对象
    let proxy = new Proxy(obj, {    // 代理
      set(target,key,val){
        target[key] = val;
      },
      get(target,key){
        return target[key]
      }
    })
    proxy.name = 'terry'    // 面向代理使用
  2. 函数 apply
    let foo = function(msg){console.log(msg);}
    let proxy = new Proxy(foo, {
      apply(target,that,args){
        target.apply(that,args)
      }
    })
  3. 构造函数 constructor
    let Person = function(name){this.name = name}

    let proxy = new Proxy(Person,{
      constructor(target,args){
        return new target(...args)
      }
    })

十三、 反射

  与代理一一对应,为代理提供操作方法:操作set/操作get/操作apply/操作contructor
    let proxy = new Proxy(obj, {    // 代理
      set(target,key,val){
        Reflect.set(target,key,val)
      },
      get(target,key){
        return Reflect.get(target,key)
      }
    })
  ...

十四、 Promise

  1. axios
    异步操作的解决方案,常用于封装ajax
    axios就是基于Promise对Ajax的封装
    0) 特点
      XMLHttpRequests(浏览器) 、http(nodejs)
      默认将data(post)转换为json
      params(get)
      支持Promise
    1) nodejs中应用(http)
      安装cnpm
      $ npm install cnpm -g --registry=https://registry.npm.taobao.org
      $ npm init
      $ cnpm install axios --save
    2) 实例化
      axios
      配置属性
        {
          method
          url
          params
          data
        }

    3) 全局配置
    4) 拦截器
    5) 快捷方法 
  2. 原生ajax的封装
    function loadArticles(){
      // 待定
      return new Promise((resolve,reject)=>{
        let xhr = new XMLHttpRequest()
        xhr.open()
        xhr.setRequestHeader()
        xhr.send()
        xhr.onreadystatechange = function(){
          if(this.readyState === 4){
            if(this.status === 200){
              // 待定-> 成功 (执行then中的回调)
              resolve(this.response);
            } else {
              // 待定 -> 失败(执行catch中的回调)
              reject(this.response);
            }
          }
        }
      })
    }

    loadArticles().then().catch().finally()
  3. 成员方法
    then/catch/finally 返回值都是一个承诺对象

    Promise.prototype.then(successHandler[,errorHandler])

    Promise.prototype.catch(errorHandler)
    等价于
    Promise.prototype.then(null,errorHandler)

    Promise.prototype.finally(handler)
  4. 静态方法
    Promise.all([p1,p2,...])
      该方法返回值为promise,当p1,p2,...全部执行完毕并且状态resolved的时候,promise的then才会被调用,该then的回调函数的参数是p1,p2,...的运行结果
      案例:当查询完所有的班级,渠道后在调用查询学生的接口;查询学生的时候默认查询第一个班级
      Promise.all(p1,p2).then((result)=>{
        let defaultClazz = result[0].data.data[0]
        loadStudent();
      })
    Promise.race(iterable)
      返回值为promise,返回率先改变状态的promise结果
    Promise.allSettled(iterable)
      返回值为promise,与all不同,当所有的承诺对象状态被确认的时候会执行promise的then,then的参数为结果
    Promise.resolve(val)
      直接返回一个承诺对象,并且状态为成功
      new Promise(resolve => {
        resolve(val);
      })
    Promise.reject(error)
      直接返回一个承诺对象,并且状态为失败
      new Promise((resolve,reject) => {
        reject(error);
      })
    iterable 可迭代的对象,常见的是数组或set...,可迭代对象中的元素是promise实例

十五、 迭代器

  0. 执行过程
    next() 调用 -> 指针
  1. ES6可迭代的对象
    数组、字符串、set、map
    实例对象可以直接访问Symbol.iterator,构造函数实现了Symbol.iterator接口
  
    // 标准
    inteface Iterator {
      [Symbol.iterator]():void;
    }
    // 类 == 构造函数 Array String Set Map
    class Array implements Iterator{
      [Symbol.iterator]():void{
      }
    }
    let arr = [1,2,3]
    arr[Symbol.iterator]()
    for(let a of arr){}
  2. 触发迭代器执行的场景
    ...
    for-of
    new Set()/new Map()
    Array.from()
    Promise.all()
    Promise.race()

十六、 generator函数

  1. 迭代器函数本质上就是一个generator函数
  手动实现一个类数组构造函数,并且该构造函数实现了Symbol.iterator接口

  function* foo(){
    yield 'terry';
    yield 'larry';
    yield 'tom';
  }

  2. next参数
  next参数可以作为上⼀个yield表达式的返回值
  
  let iterator = foo()
  iterator.next(1)

十七、 异步函数

  async function foo(){
    await axios.get(url1)
    await axios.get(url2)
  }
  foo()

十八、 面向对象

ES5语法糖
  1. 构造函数
    function Animal(name,age){
      this.name = name;
      this.age = age;
    }
    let animal = new Animal('terry',12);
    -------------------------------------
    class Animal {
      constructor(name,age){
        this.name = name;
        this.age = age;
      }
    }
    let animal = new Animal('terry',12);
  语法:
    class 为关键字
    Animal 为类名,类名首字母大写,采用驼峰命名
    {} 为类体,其中可以包含:
      构造函数、
      成员属性、
      成员方法、
      静态方法、
      静态属性、
      静态代码块(node16才支持)
  2. 实例对象
    通过构造函数创建的对象
    plain object 纯对象({},new Object())
  3. 原型方法 - 成员方法/实例方法
     class Animal {
       name;        //  成员自身中
       sayName(){   //  原型

       }
       sayAge(){

       }
     }
  4. 构造函数方法 - 静态方法
     class Animal {
       sayAge(){

       }
       static foo(){    // 类,通过类名直接调用

       }
     }
 5. 继承

    原型链继承:子构造函数的原型指向父构造函数的实例
    借用构造函数:
    

` function Dog (name,age,gender){ Animal.call(this,name,age) this.gender = gender; } Dog.prototype = new Animal(); Dog.prototype.constructor = Dog; Dog.prototype.xxx 实例方法 Dog.xxx 构造函数方法 --------------------------- class Dog extends Animal{ constructor(name,age,gender){ super(name,age) this.gender = gender; } sayGender(){

      }
    }

十九、 模块化

  任何一个js文件或者是目录都可以认为是一个模块,如果目录作为一个模块,那么,目录中应该出现package.json
  $ npm init -y
  $ npm install qs --save
    连接互联网,获取qs库?中央仓库 ,下载当前目录的node_modules
    --save  本地安装并且将其安装信息写入到package.json中 dependencies

CommonJS 模块化 社区提供的 1. 模块的暴露 模块内部的变量其他模块是无法访问,如果想要其他模块进行访问,需要进行接口的暴露 module.exports

  module是一个对象,每个模块都拥有这个对象,exports属性是用于将当前目录信息传递到其他模块,其默认值是一个空对象
  module.exports.xxx
  或者
  module.exports = {}
2. 模块引用
  require(模块)
  1. 当模块为自定义模块的时候,参数为文件路径
    require('./a.js')
  2. 当模块为内置模块的时候,参数为模块名称
    require('http')
  3. 当模块为第三方模块的时候,参数为模块名称,但是需要先进行模块的安装
    $ cnpm install axios --save
    require('axios');

  模块引入本质的就是获取被引入模块中的module.exports属性。

ES6 模块化 官方提供的 如果想要让nodejs支持es6模块化:node版本v14+ , package.json添加一个配置项 type:"module"

模块暴露:
  export 声明
    多次使用,使用哪个变量暴露,就要使用哪个变量获取
  export default 
    尽可使用一次,可以使用任意变量名来获取
  一个模块中可以既使用export又使用export default

模块导入
  import aa from './a.js