美文网首页
Understanding ECMAScript6(中)

Understanding ECMAScript6(中)

作者: Michael_lpf | 来源:发表于2017-02-23 21:07 被阅读0次


    Part 1:Set 和 Map


    Set 数据结构
    • Set 是无重复值的有序列表。
      可以对它包含的数据快速访问。
      使用 new Set() 来创建一个 Set 数据结构👇
    let set = new Set();
    

    使用 add() 方法为 Set 添加项目;
    它有一个 size 属性可查看其中包含多少项👇

    set.add(66);
    set.add('66');
    set.size  //  2
    

    👆 Set 不使用强制转换来判断值是否重复,数字66和字符串66是两个独立的项。
    如果使用 add() 重复添加了某项,之后的调用会被忽略👇

    Paste_Image.png
    • 使用 has() 判断某个项目是否存在👇
    Paste_Image.png
    • 使用 delete() 移除一个项目👇
    Paste_Image.png
    • 使用 clear() 清空整个 Set👇
    Paste_Image.png
    • 用数组初始化一个 Set👇
    Paste_Image.png

    因为 Set 是无重复值的列表,所以只保留了1,3,4三个值。
    🚫用其它类型数据尝试使用类似数组初始化 Set 都是行不通的。


    Set 的 forEach()方法

    forEach() 方法被传递一个回调函数,该回调接收三个参数:

    • 1: Set 中下一个位置的值

    • 2: 与第一个参数相同的值

    • 3: Set 本身
      与其它拥有 forEach() 方法的数据结构(也就是数组和 Map)最明显的不同是:Set 的 forEach() 方法接收的回调函数的参数,很奇怪,为什么前两个参数要一样?
      其实就是为了保持 forEach() 一致。
      为此,ES6特意为 Set 中的每个项目同时认定为“键”与“值”。

      Paste_Image.png
    • Set 有点是可以很方便地追踪一个值,并且可以用 forEach() 按顺序处理每一项,但它无法像数组那样用索引来访问某个值。

    • 我们可以将它转换成数组👇

    Paste_Image.png
    👆使用 ... 扩展运算符接收 Set 对象,同时,Set 也已经将数组去重复。
    💡这是一个非常实用的数组去重复技巧。
    Map 数据结构
    • Map 是键值对有序列表
    • 使用 set() 方法为 Map 添加一对键值
    let map = new Map();
    map.set('name', 'Rogger');
    map.set('year', 2017);
    

    Map.set()Set.add() 有些相似,需要注意的是,Map.set() 多次设置一个项目时,后者覆盖前者👇

    Paste_Image.png
    • 使用 get() 方法访问某个值
    Paste_Image.png
    • 拥有与 Set 一样的三个方法和一个属性:
      Map.has()
      Map.delete()
      Map.clear()
      Map.size

    • 使用数组初始化 Map

    let map = new Map( [ ['name', 'Bean'], ['age', 42] ] );
    

    👆不同于数组初始化 Set 之处是,数组初始化 Map 时,数组中的每一项也必须是数组。
    因为这样才能准确表达 Map 中的每个项目都是键值对。


    Map 的 forEach()方法

    forEach() 方法接收的回调函数同样接收三个参数:

    • 1:Map 中下一个位置的值
    • 2:该值对应的键
    • 3:Map 本身
    Paste_Image.png

    Part 2: 增强的数组功能


    创建数组的新方法
    • Array.of() 方法
      之前我们使用 new Array() 构造器创建一个数组时,传入的参数类型和数量是可以影响最终结果的。
      传入单个数值参数时,数组长度被设置为该参数,
      传入单个非数值参数时,参数则成为该数组的项👇
      Paste_Image.png
    Paste_Image.png

    当传入多个参数时(无论数值与否),所有参数都成为数组的项👇

    Paste_Image.png Paste_Image.png
    ES6 中引入的 Array.of() 方法,接收的参数将永远作为数组的项👇 Paste_Image.png Paste_Image.png

    Array.of() 方法避免了 new Array() 构造器可能造成的混乱,今后可以考虑用 Array.of() 来代替构造器。

    • Array.from() 方法
      将可迭代对象或者类数组对象作为参数传入 Array.from() 就能返回一个数组
      常见场景是,将 arguments 转化为数组👇
      Paste_Image.png
      将 nodeList 转换为数组👇
    Paste_Image.png
    • 可以向 Array.from 传入一个用作映射的函数作为第二个参数👇
      Paste_Image.png
      如此便完成了一个批量处理👆

    数组新方法
    • find()findIndex() 方法
      接收一个回调函数,该函数在给定元素满足定义的时候返回 true。
      当回调函数第一次返回 true 时,find()/findIndex() 便停止查找。
      不同之处是 find() 返回匹配的值,findIndex() 返回匹配值的位置👇
    Paste_Image.png Paste_Image.png
    • fill()方法
      该方法用指定值来填充数组👇
      Paste_Image.png
      接收第二个可选参数作为填充起始位置,接收第三个可选参数作为填充结束位置(填充范围不包含结束位置)👇
    Paste_Image.png
    • copyWithin() 方法
      copyWithin() 方法允许在数组内部“复制粘贴”自身元素,它接收两个参数,一是从何位置开始“粘贴”,二是从何位置开始“复制”:
    Paste_Image.png

    👆从数组的第2个位置开始粘贴,从数组第0个位置开始复制(一直复制到数组末尾)
    可以传入第三个可选的参数来控制多少元素被覆盖👇

    Paste_Image.png

    Part 3:生成器与迭代器


    可迭代对象与 for-of 循环

    在过去我们遍历一个数组时,需要这样👇

    Paste_Image.png

    在 ES6 中,所有集合对象(数组,Set,Map)都是可迭代对象,可配合新增的 for-of 使用👇

    Paste_Image.png
    与传统 for 循环相比,for-of 更容易,因为它不需要计数器也不必考虑循环何时结束。它会从迭代器中读取所有数据后退出循环。
    如果简单地迭代数组或集合的值,使用 for-of 更好,将传统的 for 留给更复杂的逻辑控制。
    集合的迭代器

    ES6 中集合迭代器(数组,Set,Map)拥有三种内置的迭代器:keys()value()entries()

    • 可以显式指定集合使用何种迭代器。
    • keys() 返回集合中的键
      对于数组,返回数值类型的键;对于 Set 返回键值相同的迭代器;对于 Map 返回不重复的键👇
    Paste_Image.png
    • entries() 返回双项目数组,代表键和值👇
    Paste_Image.png
    • 数组和 Set 的默认迭代器是 values(),Map 的默认迭代器是 entries

    字符串的迭代器

    字符串同样拥有默认迭代器👇


    Paste_Image.png
    NodeList 的迭代器

    下面代码可以打印页面中所有 div 的 id 值

    let node = document.getElementsByTagName('div');
    for(let div of node){
      console.log(div.id);
    }
    

    自定义迭代器

    了解它之前,要先说说用于返回迭代器的函数——生成器:
    生成器用放在 function 关键字之后的 * 表示,并使用新的关键字 yield 来控制“节奏”👇


    生成器可以像普通函数那样被调用,但返回的则是一个迭代器了👇
    Paste_Image.png
    yield 指定了迭代器被 next() 方法调用时的返回值👇
    Paste_Image.png
    所有迭代器都有 next() 方法,它返回两个属性:值 value 和 布尔类型的 done,当 done 值为 true 时表示迭代器没有更多的返回了。
    也可以用函数表达式的方式创建一个生成器👇
    Paste_Image.png
    • 作为方法的生成器的书写方法
      ES5 中的传统写法👇


      Paste_Image.png

      ES6 中的简写写法👇


      Paste_Image.png
    • 要注意的是, yield 关键字必须严格在生成器的内部,即是是生成器内部的函数内也不行👇

    Paste_Image.png
    委托生成器

    使用 yield* 配合,将生成器包裹于另一个生成器中,就获得了一个委托生成器👇

    Paste_Image.png
    生成器委托对迭代器的行为进行了良好的组织。

    Part 4:符号


    • ES5 中的基本类型:String/Number/Boolean/Undefined/Null/Object。
      ES6 引入了新的基本类型:Symbol(符号)。

    • 符号没有字面量形式,这是 JS 中独一无二的。
      使用 Symbol() 创建一个符号👇

    Paste_Image.png
    • Symbol() 接收一个参数作为它的描述,这个描述内容不能访问,但可以用来调试👇
    Paste_Image.png
    • 它作为对象属性时,不可枚举👇

      Paste_Image.png
      可以在需要使用“计算属性名”的场景中使用符号👆
      💡在对象内部使用符号时,需要使用 [] 来操作。
    • 使用 Symbol.for() 登记一个符号供全局共享👇

      Paste_Image.png
      👆通过向 Symbol.for() 传入参数,sy3/sy4 引用了同一个符号。
      Symbol.for() 调用时不会先返回新符号,而是在全局注册表中查找是否有已存在的符号,如有则返回,如没有则新建👇
      Paste_Image.png
      ❓生产中的用处

    一些知名符号:

    Symbol.hasInstance:供 instanceof 运算符使用,用于判断继承关系。
    Symbol.isConcatSpreadable:布尔类型值,在集合参数传递给 concat() 方法时,指定集合是否展开。
    Symbol.match:比较字符串。
    Symbol.replace:替换字符串。
    Symbol.search:定位字符串。
    Symbol.split:用于分割字符串。
    Symbol.species:用于派生对象构造器。
    Symbol.toPrimitive:返回对象对应的基本类型。
    Symbol.iterator:返回迭代器的一个方法。

    • Symbol.iterator 迭代符号
      尝试直接用 for-of 迭代一个对象字面量行不通👇
      Paste_Image.png
      使用迭代符号改写后的 obj 👇
      Paste_Image.png
      可迭代的数据集合(数组,Set,Map)之所以可以直接迭代就是因为已经部署好了 [Symbol.iterator]
      原因在于,这些数据结构原生部署了Symbol.iterator属性,另外一些数据结构没有。凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。——阮一峰


    本节完
    Understanding ECMAScript6(上)
    Understanding ECMAScript6(下)

    相关文章

      网友评论

          本文标题:Understanding ECMAScript6(中)

          本文链接:https://www.haomeiwen.com/subject/qgsuwttx.html