美文网首页
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