ECMAScript6

  • 变量

    1. let    不能重复声明;变量-可以修改;块级作用域;不存在变量提升
    2. const 不能重复声明;常量-不能修改;块级作用域;对于数组和对象的元素修改,不算做对常量的修改,不会报错
  • 函数 - 箭头函数

    1
    2
    3
    4
    5
    function(){} ----> ()=>{}

    // 如果只有一个参数,()可以省略
    // 如果只有一个return,{}可以省略
    function(a){return(a*2)} ----> a => a*2
    1. this 是静态的,this始终指向函数声明时所在作用域下的this的值
    2. 不能作为构造函数实例化对象
    3. 不能使用 arguments 变量
  • 函数 - 参数

    1. 参数扩展
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      //收集参数
      function show(a, b, ...c){} //...c必须是最后一个
      show(1,2,3,4,5);
      a //1
      b //2
      c //[3,4,5]
      ...c // 3 4 5

      //展开参数
      //展开后的效果,跟直接把数组内容写在这一样
    2. 默认参数
      1
      function(a, b=1, c=2){}
    3. rest ES6引入 rest 参数,用于获取函数的实参,用来代替 arguments
  • 解构赋值

    1. 左右两边结构必须一样
    2. 右边必须是个东西
    3. 声明和赋值不能分开(必须在一句话里完成)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      let [a, b, c] = [1, 2, 3];

      console.log(a, b, c); //1 2 3

      // --------------------------------------

      function breakfast(){
      return {dessert: 1, drink: 2, fruit: 3};
      }

      let {dessert: dessert, drink: drink, fruit: fruit} = breakfast();

      console.log(dessert, drink, fruit); // 1 2 3
  • 数组

    1. map 映射

      1
      2
      3
      4
      5
      6
      7
      8
      let arr = [12, 5, 8];
      let result = arr.map(function(item){ //let result = arr.map(item => item);
      return item;
      });
      let score = arr.map(item => item>10?'大于10':'不大于10');

      console.log(result); //[12, 5, 8]
      console.log(score); //['大于10', '不大于10', '不大于10']
    2. reduce 汇总 一堆出来一个

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      let arr = [10, 11, 12, 13];
      let sum = arr.reduce(function(tmp, item, index){ //求和
      return tmp + item;
      });
      let average = arr.reduce(function(tmp, item, index){ //求平均数
      if(index != arr.length-1){
      return tmp + item;
      }else{
      return (tmp + item) / arr.length;
      }
      });

      console.log(sum); //46 求和
      console.log(average); //11.5 求平均数
    3. fill 填充数组
      参数:填充的内容, 起始位置, 结束位置

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      let result = arr.fill(6);
      console.log(result); //[6, 6, 6, 6, 6]

      //-----------------------

      let arr = [1, 2, 3, 4, 5];
      let result = arr.fill(6, 2);
      console.log(result); //[1, 2, 6, 6, 6]

      //------------------------

      let arr = [1, 2, 3, 4, 5];
      let result = arr.fill(6, 2, 3);
      console.log(result); //[1, 2, 6, 4, 5]
    4. filter 过滤器

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
      let result = arr.filter(item => {
      if(item % 2 == 0){
      return true;
      }
      });

      console.log(result); //[2, 4, 6, 8]

      //--------------- 简写

      let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
      let result = arr.filter(item => item % 2 == 0);

      console.log(result); //[2, 4, 6, 8]
    5. Array.from() 将类数组对象转为真正的数组

      1
      2
      let str = '123456';
      console.log(Array.from(str)); // ['1', '2', '3', '4', '5', '6']
    6. Array.of() 将一组参数转换为数组

      1
      console.log(Array.of(1, 2, 3, 4, 5, 6)); // ['1', '2', '3', '4', '5', '6']
    7. find 找出第一个符合条件的数组元素
      参数:
      · 回调函数
      · 回调函数内this指向

      遍历整个数组,遍历过程中调用回函数,如果回调函数的返回值为true,则返回当前在遍历的元素。
      如果所有元素都不符合条件则返回 undefined

      1
      2
      3
      4
      5
      let arr = [1, 2, 3, 4, 5, 6];
      let num = arr.find(function(value, index){
      return value > 4;
      });
      console.log(num); //5
    8. findIndex 找出第一个符合条件的数组元素的索引
      参数:
      · 回调函数
      · 回调函数内this指向

      遍历整个数组,遍历过程中调用回函数,如果回调函数的返回值为true,则返回当前在遍历的元素位置。
      如果所有元素都不符合条件则返回 -1

      1
      2
      3
      4
      5
      let arr = [1, 2, 3, 4, 5, 6];
      let num = arr.findIndex(function(value, index){
      return value > 4;
      });
      console.log(num); //4
    9. for of 遍历拥有遍历接口对象的属性值

      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
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      let arr = [1, 2, 3, 4, 5, 6];
      for(value of arr){
      consolelog(value);
      }
      //1
      //2
      //3
      //4
      //5
      //6

      //----------------------------

      //遍历数组键名
      let arr = [1, 2, 3, 4, 5, 6];
      for(let key of arr.keys()){
      console.log(key);
      }
      //0
      //1
      //2
      //3
      //4
      //5

      //----------------------------

      //遍历数组键值
      let arr = [1, 2, 3, 4, 5, 6];
      for(let value of arr.values()){
      console.log(value);
      }
      //1
      //2
      //3
      //4
      //5
      //6

      //----------------------------

      //遍历数组键值对
      let arr = [1, 2, 3, 4, 5, 6];
      for(let [key, value] of arr.entries()){
      console.log(key, value);
      }
      //0 1
      //1 2
      //2 3
      //3 4
      //4 5
      //5 6
    10. for Each 循环(迭代)

  • 字符串

    1. 多了几个新方法
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //includes
      let str = 'abcdefg';
      console.log(str.includes('a')); //true

      //startsWith
      let str = 'abcdefg';
      console.log(str.startsWith('a')); //true

      //endsWidth
      let str = '1.text';
      console.log(str.endsWith('text')); //true
    2. 字符串模板 字符串连接
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      //直接串塞到字符串里边
      //可以折行
      let str1 = 'abcdefg';
      let str2 = `12345${str1}6789`;
      console.log(str2); //12345abcdefg6789

      //--------------------

      //可以添加标签
      let str1 = 'abcdefg';
      let str2 = `123456789`;
      let breakfast = mark`数字:${str1},字符串:${str2}`;

      function mark(string, ...values){
      console.log(string); // ["数字:", ",字符串:", "", raw: Array(3)], raw: (3) ["数字:", ",字符串:", ""]
      console.log(values); // ["abcdefg", "123456789"]
      }
  • 数值

    1. 二进制和八进制表示法
      ES6提供了人二进制和八进制数值的新的写法,分别用前缀 0b0o 表示。
      1
      2
      3
      4
      let num1 = 0b11;  //3    二进制
      let num2 = 0o11; //9 八进制
      let num3 = 100; //100 十进制
      let num4 = 0xff; //255 十六进制
    2. Math对象的扩展
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      //Math.trun 去除小数部分,返回整数部分
      let num = 1.23456;
      console.log(Math.trunc(num)); //1

      //Math.sign 判断一个数字是正数、负数还是零
      let num1 = 10;
      let num2 = -10;
      let num3 = 0;
      let num4 = -0;
      console.log(Math.sign(num1)); //1
      console.log(Math.sign(num2)); //-1
      console.log(Math.sign(num3)); //0
      console.log(Math.sign(num4)); //-0

      //Math.hypot 返回所有参数的平方和的平方根(勾股定理)
      console.log(Math.hypot(3, 4)); //5
    3. Number.EPSILON 是JavaScript表示的最小精度
      EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      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
    4. Number.isFinite 检测一个数值是否为有限数
      1
      2
      3
      console.log(Number.isFinite(100));      //true
      console.log(Number.isFinite(100/0)); //false
      console.log(Number.isFinite(Infinity)); //false
    5. Number.isNaN 检测一个数值是否为NaN
      1
      console.log(Number.isNaN(123));         //false
    6. Number.parseInt Number.parseFloat 字符串转整数
      1
      2
      console.log(Number.parseInt('123wq'));  //123
      console.log(Number.parseFloat('13.44'));//13.44
  • 对象表达式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let dessert = 1;
    let deink = 2;
    let food = {
    dessert: dessert,
    deink: deink,
    breakfast: function(){}
    }
    // -----------------------
    let food = {
    dessert,
    deink,
    breakfast(){}
    }
  • 对象属性名

    1
    2
    3
    4
    5
    6
    let food = {};
    let drink = 'hot drink';

    food.dessert = 1;
    food['hot dog'] = 2;
    food[drink] = 3;
  • 对比两个值是否相等 Object.is()

    1
    2
    console.log(Object.is(NaN, NaN)); //true
    console.log(Object.is(+0, -0)); //false
  • 把对象的值复制到另一个对象里 Object.assign()

    1
    2
    3
    4
    5
    6
    7
    8
    let breakfast = {};

    Object.assign(
    breakfast,
    {drink: 1}
    )

    console.log(breakfast); //{drink: 1}
  • 设置对象的 prototype Object.setPrototypeOf()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    let breakfast = {
    getDrink(){
    return 1;
    }
    }
    let dinner = {
    getDrink(){
    return 2;
    }
    }
    let sunday = Object.create(breakfast);
    console.log(sunday.getDrink()); // 1
    console.log(Object.getPrototypeOf(sunday) === breakfast); //true

    Object.setPrototypeOf(sunday, dinner);
    console.log(sunday.getDrink()); // 2
    console.log(Object.getPrototypeOf(sunday) === dinner); //true
  • __proto__

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    let breakfast = {
    getDrink(){
    return 1;
    }
    }
    let dinner = {
    getDrink(){
    return 2;
    }
    }
    let sunday = {
    __proto__: breakfast
    }

    console.log(sunday.getDrink()); // 1
    console.log(Object.getPrototypeOf(sunday) === breakfast); // true

    sunday.__proto__ = dinner;
    console.log(sunday.getDrink()); // 2
    console.log(Object.getPrototypeOf(sunday) === dinner); // true
  • super

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let breakfast = {
    getDrink(){
    return 1;
    }
    }
    let sunday = {
    __proto__: breakfast,
    getDrink(){
    return super.getDrink();
    }
    }

    console.log(sunday.getDrink()); // 1
  • 迭代器 Iterators

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

    1. ES6创造了一种新的遍历命令 for...of 循环,Iterator 接口主要提供 for...of 消费
    2. 原生具备 Iterator 接口的数据(可用 for...of 遍历)
      · Array
      · Arguments
      · Set
      · Map
      · String
      · TypeArray
      · NodeList
    3. 工作原理
      · 创建一个指针对象,指向当前数据结构的起始位置
      · 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
      · 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
      · 每调用 next 方法返回一个包含 valuedone 属性对象
      注:需要自定义遍历数据的时候,需要想到迭代器。
  • generator 生成器

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

  • 面向对象

    1. class关键字、构造器和分类分开了
    2. class里面直接加方法
      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
      32
      33
      34
      35
      36
      class User{
      constructor(name, pass){
      this.name = name;
      this.pass = pass;
      }

      showName(){
      console.log(this.name);
      }

      showPass(){
      console.log(this.pass);
      }
      }

      let u1 = new User('名字', '密码');

      u1.showName(); //名字
      u1.showPass(); //密码

      //---------------- 继承

      class vipUser extends User{
      constructor(name, pass, level){
      super(name, pass);
      this.level = level;
      }

      showLevel(){
      console.log(this.level);
      }
      }

      let v1 = new vipUser('名字', '密码', '等级');

      v1.showLevel(); //等级
  • JSON

    1. JSON标准写法
      • 只能用双引号
      • 所有的名字(key)都必须用引号抱起来
    2. JSON对象
      1
      2
      JSON.stringify  //转字符串
      JSON.parse //转JSON
    3. 简写
      • 名字跟值(key跟value)一样,留一个就行
      • 方法
        show:function(){}
        show(){}
  • Symbol

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

    特点:
    1)Symbol的值是唯一的,用来解决命名重瞳的问题
    2)Symbol值不能与其他数据进行计算
    3)Symbol定义的对象属性不能用 for...in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //创建Symbol
    let s = Symbol();
    console.log(s, typeof s); //Symbol() symbol

    let s2 = Symbol('张三');
    let s3 = Symbol('张三');
    console.log(s2, s3, s2===s3); //Symbol(张三) Symbol(张三) false

    let s4 = Symbol.for('李四');
    let s5 = Symbol.for('李四');
    console.log(s4, s5, s4===s5); //Symbol(李四) Symbol(李四) true
  • Promise

    Promise是ES6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
    · Promise构造函数:promise(excutor){}
    · Promise.prototype.then方法
    · setPromise.prototype.catch方法

  • Set

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

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    //声明一个set
    let s1 = new Set();
    let s2 = new Set([1, 2, 3, 4, 3]);
    console.log(s1, typeof s1); //Set(0) object
    console.log(s2); //Set(4) {1, 2, 3, 4}

    //size 返回集合的元素个数
    console.log(s2.size); //4

    //add 添加新元素,返回当前集合
    s2.add(9);
    console.log(s2); //Set(5) {1, 2, 3, 4, 9}

    //delete 删除元素,返回 boolean 值
    s2.delete(1);
    console.log(s2); //true

    //检测,是否包含
    s2.has(1);
    console.log(s2); //true

    //清空
    s2.clear()
    console.log(s2); //Set(0)

    //遍历
    for(v of s2){
    console.log(v);
    }
    //1
    //2
    //3
    //4

    //实例
    let arr = [1, 2, 3, 4, 5, 6, 1, 2, 3];

    //数组去重
    let result = [...new Set(arr)];
    console.log(result); //[1, 2, 3, 4, 5, 6]

    //交集
    let arr2 = [4, 5, 6, 4, 5, 6, 7];
    let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
    console.log(result); //[4, 5, 6]

    //并集
    let result = [...new Set([...arr, ...arr2])];
    console.log(result); //[1, 2, 3, 4, 5, 6, 7]

    //差集
    let result = [...new Set(arr)].filter(itme => !(new Set(arr2).has(itme)));
    let result2 = [...new Set(arr2)].filter(itme => !(new Set(arr).has(itme)));
    console.log(result); //[1, 2, 3]
    console.log(result2); //[7]
  • Map

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

    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
    //声明Map
    let m = new Map();

    //set 增加一个新元素,返回当前Map
    m.set('name', '张三'); //Map(1) {name => 张三}
    m.set('fn', function(){}); //Map(1) {fn => ƒ (){}}

    let key = {
    sex: '性别'
    };
    m.set(key, ['男', '女', '未知']); //Map(1) {{sex: '性别'} => (3) ['男', '女', …]}

    //size 返回Map的元素个数
    consle.log(m.size); //3

    //删除
    m.delete('name'); //Map(2) {fn => ƒ (){}, {sex: '性别'} => (3) ['男', '女', …]}

    //获取 get 返回键名对象的键值
    m.get('fn');
    m.get(key);

    //clear 清空集合,返回 undefined
    m.clear();

    //遍历
    for(i of m){}

    //has 检测 Map 中是否包含某个元素,返回boolean值
    m.has('name');
  • Class

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

    1. class 声明类
    2. constructor 定义构造函数初始化
    3. extends 继承父类
    4. super 调用父级构造方法
    5. static 定义静态方法和属性
    6. 父类方法可以重写
    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
    class Phone{
    //构造方法 名字constructor不能修改
    constructor(brand, price){
    this.brand = brand;
    this.price = price;
    }

    //方法必须使用改语法,不能使用ES5的对象完整形式
    call(){
    console.log('我可以打电话');
    }
    }

    let huaWei = new Phone('HuaWei', 4999);
    huaWei.call(); //我可以打电话
    console.log(huaWei); //Phone {brand: 'HuaWei', price: 4999}

    //继承
    class SmartPhone extends Phone{
    constructor(brand, price, color, size){
    super(brand, price);
    this.color = color;
    this.size = size;
    }

    //重写方法
    call(){
    console.log('我可以打视频电话');
    }
    }
  • 模块化

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

    好处:
    · 防止命名冲突
    · 代码复用
    · 高维护性

    ES6之前的模块化规范
    · CommomJS => NodeJS、Browserify
    · AMD => requireJS
    · CMD => seaJS

    ES6模块化语法
    模块功能主要有两个命令组成:export 和 import
    · export 命令用于规定模块的对外接口
    · import 命令用于输入其他模块提供的功能