let

  • 变量不能重复生命

    1
    2
    let star = 'start'
    let star = 'start' // error
  • 块儿级作用域

    1
    2
    3
    4
    5
    6
    7
    {
    let star = 'start'
    }
    console.log(star) // error

    // if else while for

  • 不存在变量提升

    1
    2
    console.log(start) //error
    let start = 'star'
  • 不影响作用域链

    1
    2
    3
    4
    5
    6
    7
    {
    let star = 'star';
    function outStar() {
    console.log(star);
    }
    outStar();
    }
  • 案例练习

    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

    <style>
    .app ul li {
    display: inline-block;
    width: 100px;
    height: 50px;
    border: 2px solid skyblue;
    }
    </style>

    <div class="app">
    <ul>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    </ul>
    </div>

    <script>
    const items = document.querySelectorAll('.item');
    for (let item = 0; item < items.length; item++) {
    console.log(item);
    items[item].onclick = function () {
    items[item].style.background = 'blue';
    };
    }
    // let 为 var 时,item结果为 3 ,无法执行内部函数
    console.log(window.item);
    </script>

const

  • 定义常量
  • 一定要赋初始值
  • 潜规则变量大写
  • 块级作用域

解构

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

  • 数组解构

    1
    2
    3
    4
    5
    6
    //  数组的解构
    const ARRAR = ['A', 'B', 'C'];
    // a,b,c 就是数组元素对应的值
    let [a, b, c] = ARRAR;
    console.log(a);
    console.log(b);
  • 对象解构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let coderitl = {
    name: 'coderitl',
    age: '不详',
    study() {
    console.log('正在学习es6...');
    }
    };
    // 简化对象值的获取
    let { name, age, study } = coderitl;

    console.log(name); // coderitl
    console.log(age); // 不详
    console.log(study); // 正在学习es6...

    study() // 函数调用


    // 对象的属性获取,解构可以简化如下操作
    coderitl.name
    coderitl.age

    • 输出

      解构对象
      解构对象

模板字符串

  • 声明

    1
    2
    let str = `aa`
    console.log(str,typeof str);
  • 内容中可以直接出现换行符

    1
    2
    3
    4
    5
    let str = `
    <ul>
    <li></li>
    </ul>
    `;
  • 拼接变量

    1
    2
    3
    let name = `coderitl`;
    let cd = `${name}正在学习 Es6`
    console.log(cd);

对象简写

  • Es6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let name = 'coder-itl';
    let change = function () {
    console.log('我们改变你!');
    };
    const info = {
    name,
    change,
    };
    console.log(info);
    • 输出对比

      对象简写
      对象简写

箭头函数

  • 声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 普通函数
    let userName1 = function(){
    console.log('coder-itl-1');
    }
    // 箭头函数
    let userName2 = ()=>{
    console.log('coder-itl-2');
    }
    // 函数调用
    userName1()
    userName2()
  • 特性

    • this 是静态的,this 始终指向函数声明时所在作用域下的this 的值

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      let userName1 = function () {
      console.log('coder-itl-1');
      console.log('userName1:',this.name);
      };
      let userName2 = () => {
      console.log('coder-itl-2');
      console.log('userName2:',this.name);
      };
      window.name = 'global coder-itl';
      const school = {
      name: '育才中学'
      };

      userName1();
      userName2();
      console.log('------------');
      userName1.call(school)
      userName2.call(school)
      • 输出对比

        this 指向
        this指向
    • 不能为构造函数实例化

      1
      2
      3
      4
      5
      6
      let Person = (name, age) => {
      this.name = name;
      this.age = age;
      };
      let person = new Person();
      console.log(person);
      • 输出

        箭头函数不能为构造函数实例化
        箭头函数不能为构造函数实例化
    • 不能使用arguments 变量

      arguments
      arguments

rest参数

  • 使用

    1
    2
    3
    4
    function date(...args) {
    console.log(args);
    }
    date('A', 'B', '白芷');
    • 输出

      rest 参数
      rest参数
    • 注意: 在有其他参数时,该参数必须放在最后

扩展运算符

  • ... 扩展运算符能将[数组] 转换为逗号分隔的参数序列

  • 使用

    1
    2
    3
    4
    5
    6
    7
    8
    // 声明一个数组
    const tfboys = ['易烊千玺', '王源', '王俊凯'];
    // 声明一个函数
    function fn() {
    console.log(arguments);
    }
    // 等价于 fn('易烊千玺', '王源', '王俊凯')
    fn(...tfboys);
    • 输出

      ...
      ...
  • 数组的合并

    • concat

      concat
      concat
    • ...

      扩展运算合并数组
      扩展运算合并数组
    • 数组的克隆(浅拷贝)

      1
      2
      3
      4
      // 声明一个数组
      const tfboys = ['易烊千玺', '王源', '王俊凯'];
      const girlBoyfriends = [...tfboys];
      console.log(girlBoyfriends);
    • 将一个伪数组转换为一个真正的数组

      • 输出

        伪数组转为真实数组
        伪数组转为真实数组

Symbol 基本使用

  • 介绍

    Es6 引入了一种新的原始数据类型Symbol,表示独一无二的值,它是Javascript 语言的第其中数据类型,是一种类似于字符串的数据类型

  • 特点

    • Symbol 的值是唯一的,用来解决命名冲突的问题

    • Symbol 值不能与其他数据进行运算(自己也不行)

      symbol 不能运算
      symbol不能运算
    • Symbol 定义的对象属性不能使用for in 循环遍历,但可以使用Reflect.ownKeys 来获取对象的所有键名

  • 函数式创建

    1
    2
    3
    4
    5
    6
    7
    let s1 = Symbol();
    console.log(s1, typeof s1);
    let s2 = Symbol('内容是标识,和注释一样');
    let s3 = Symbol('内容是标识,和注释一样');
    // false
    console.log(s2 === s3);

  • Symbol.for 创建

    1
    2
    3
    4
    5
    // 可以得出唯一的 Symbol
    let s4 = Symbol.for('A')
    let s5 = Symbol.for('A')
    // true
    console.log(s4===s5);
  • 数据类型总结

    1
    2
    3
    4
    5
    6
    USONB: you are so niubility
    U undefined
    S String symbol
    o Object
    n null number
    b boolean
  • Symbol 可以给对象安全的添加方法

迭代器

  • 介绍

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

  • 特性

    • Es6 创造了一种新的便利命令for of 循环,Iterator 接口主要提供for of 消费

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

      • Array
      • Arguemnts
      • Set
      • Map
      • String
      • TypedArray
      • NodeList
    • for of 遍历数组

      1
      2
      3
      4
      let arrayWorld = ['A', 'B', 'C'];
      for (const word of arrayWorld) {
      console.log(word);
      }
    • 工作原理

      • 创建一个指针对象,指向当前数据结构的起始位置

        创建一个指针对象,指向当前数据结构的起始位置
        创建一个指针对象,指向当前数据结构的起始位置
      • 第一次调用对象的next() 方法,指针会自动指向数据结构的第一个成员

        next 方法调用
        next方法调用
      • 接下来不断调用next 方法,指针一直往后移动,直到指向最后一个成员

        连续调用next
        连续调用next
      • 每调用next 方法返回一个包含value node 属性的对象

生成器

  • 就是一个特殊的函数(异步)

  • 创建

    1
    2
    3
    4
    5
    6
    7
    function* fn() {
    console.log('Hello fn!');
    }

    let _fn = fn();
    // 真正的调用
    _fn.next();
  • yield 分割

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function* fn() {
    console.log('Hello fn!');
    yield 'H next'
    yield 'H next next'
    }

    let _fn = fn();
    // 真正的调用
    _fn.next();
    • 输出

      生成器
      生成器
    • 生成器的函数参数

      参数传递
      参数传递
    • 生成器函数实例

      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
      // 1s后输出 11 2s后输出 22 3s后输出33
      function one() {
      setTimeout(() => {
      console.log(1111);
      iterator.next();
      }, 1000);
      }
      function two() {
      setTimeout(() => {
      console.log(2222);
      iterator.next();
      }, 2000);
      }
      function three() {
      setTimeout(() => {
      console.log(3333);
      }, 3000);
      }
      function* gen() {
      yield one();
      yield two();
      yield three();
      }
      let iterator = gen();
      iterator.next()

Promise

  • 介绍

    Promise Es6 引入的异步编程的新解决方案,与发生Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

    1. Promise 构造函数: Promise(excutor){}
    2. Promise.prototype.then 方法
    3. Promise.prototype.catch 方法

Set

  • 介绍

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

  • 集合的属性和方法

    • size 返回集合的元素个数
    • add 增加一个新元素,返回当前集合
    • delete 删除元素,返回boolean
    • has 检测集合中是否包含某个元素,返回boolean
  • 输出

    Size
    Size
  • 实践

    • 数组去重

      1
      2
      3
      4
      5
      6
      7
      let arr = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
      console.log('未去重之前数组长度: ', arr.length);
      console.log(arr);
      // 数组去重
      let newArr = [...new Set(arr)];
      console.log('通过Set去重后,数组长度: ', newArr.length);
      console.log(newArr);
      • 输出

        数组去重
        数组去重
    • 交集

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      // 声明数组
      let arr1 = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
      // 声明数组
      let arr2 = [4, 5, 1, 3, 2, 4, 1];
      // 通过Set将数组1去重并过滤
      let result = [...new Set(arr1)].filter(item => {
      // 将数组2转换为 Set去重
      let s2 = new Set(arr2);
      // 通过Set 方法判断元素是否存在
      if (s2.has(item)) {
      // 存在
      return true;
      } else {
      // 不存在
      return false;
      }
      });
      console.log(result);

      // 简化
      let res = [...new Set(arr1)].filter(
      item => new Set(arr2).has(item)
      );
      console.log(res);
      • 输出

        交集
        交集
    • 并集

      1
      2
      3
      4
      5
      6
      7
      // 声明数组
      let arr1 = [1, 2, 4, 5, 1, 2, 3, 8, 9, 10, 1];
      // 声明数组
      let arr2 = [4, 5, 1, 3, 2, 4, 1];
      // 数组合并 => 转换为 Set去重 => 再转化为数组
      let union = [new Set([...arr1, ...arr2])];
      console.log(union);
    • 差集

      1
      2
      3
      4
      // S1 - S2(S1中存在,S2中不存在)
      let res = [...new Set(arr1)].filter(
      item => !(new Set(arr2).has(item))
      );

Map

  • 介绍

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

  • Map 的属性和方法

    • size 返回Map 的元素个数
    • set 增加一个新元素,返回当前Map
    • get 返回键名对象的键值
    • has 检测Map 中是否包含某个元素,返回boolean
    • clear 清空集合,返回undefined
  • 基础使用

    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
    // 声明 Map
    let map = new Map();
    // 添加
    map.set('coderName', 'coder-itl');
    map.set('coderAge', 18);
    let coderInfo = {
    address: 'BJ',
    };
    // 对象最为 key
    map.set(coderInfo, ['SH', 'HN', 'SX']);
    // value是一个函数
    map.set('change', () => {
    console.log('你有目标吗?');
    });
    // 获取 map元素个数
    console.log(map.size);
    // 获取元素怒
    console.log(map.get('coderName'));

    // 迭代器使用
    for (const iterator of map) {
    console.log(iterator);
    }
    // 删除
    map.delete('coderInfo');
    map.clear()
    console.log(map);

Class -类

  • 简介

    Es6 提供了更接近传统语言的写法,引入了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
    // 声明类
    class Phone {
    // 定义一个有参的构造函数
    constructor(brand, price) {
    // 初始化
    this.brand = brand;
    this.price = price;
    }
    // 声明一个方法 必须使用 方法名(){ // ... 方法体 }
    call() {
    console.log('正在通话中,请稍后在拨....');
    }
    }
    // 实例化
    let phone = new Phone('IQ Neno5', 2999);
    console.log(phone);
  • 静态成员

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 声明类
    class Phone {
    // 静态属性 属于类 不属于实例对象
    static name = '手机';
    static change() {
    console.log('我可以改变世界!');
    }
    }
    // 实例化
    let phone = new Phone();
    console.log(phone.name); // undefined 不属于实例对象
    console.log(Phone.name); // 属于类
  • 类继承

    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
    // 声明类
    class Phone {
    constructor(brand, price) {
    this.brand = brand;
    this.price = price;
    }
    // 父类的成员属性
    call() {
    console.log('正在通话中,请稍后再拨....');
    }
    }
    class IQNeoo5 extends Phone {
    constructor(brand, price, color, size) {
    // 调用父级构造函数
    super(brand, price);
    // 初始化子级属性
    this.color = color;
    this.size = size;
    }
    // 子级特有成员属性
    photo() {
    console.log('我拍了一张照片!');
    }
    playGame() {
    console.log('我正在进行xxx游戏中....');
    }
    }

    // 实例化
    let phone = new IQNeoo5('IQNeno5', 1999, '红色', 6.54);
    console.log(phone);

    // 调用父级方法
    phone.call()

  • 子类对父类方法的重写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 父类有 call
    // 子类重写
    class IQNeoo5 extends Phone {
    constructor(brand, price, color, size) {
    // 调用父级构造函数
    super(brand, price);
    // 初始化子级属性
    this.color = color;
    this.size = size;
    }
    // 子级特有成员属性
    photo() {
    console.log('我拍了一张照片!');
    }
    playGame() {
    console.log('我正在进行xxx游戏中....');
    }
    // 重写 子类不能直接调用父类方法
    call(){
    console.log('完全重写了父类....');
    }
    }
  • get set

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 声明类
    class Phone {
    get price() {
    console.log('price 属性被读取了');
    return 'data';
    }
    // 需要传入一个参数
    set price(val) {
    console.log('price 被修改时将会被调用...');
    }
    }
    // 实例化对象
    let phone = new Phone();
    // 读取属性
    console.log(phone.price);
    phone.price = 'free';