1 symbol

ES6 新增的基本数据类型,表示独一无二的值。
不可以用new,可已传入描述性参数
image.png
这样可已来解决对象属性名可能冲突的问题。

  1. // 使用Symbol值模拟私有方法
  2. const fetch = Symbol('fetchData');
  3. class DetailService extends Service {
  4. // 避免覆盖框架提供的同名方法
  5. async [fetch]({ apis = [] } = {}) {
  6. ......
  7. }
  8. }

Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。

它也不是私有属性,有一个Object.getOwnPropertySymbols()方法, 可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

  1. const obj = {};
  2. const foo = Symbol('foo');
  3. obj[foo] = 'bar';
  4. for (let i in obj) {
  5. console.log(i); // 无输出
  6. }
  7. Object.getOwnPropertyNames(obj) // []
  8. Object.getOwnPropertySymbols(obj) // [Symbol(foo)]

由于以 Symbol 值作为键名,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。

ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。
其中Symbol.iterator需要知道,这个跟遍历器有关,对象的Symbol.iterator属性指向该对象的默认遍历器方法。对象进行for…of 循环时,会调用Symbol.iterator方法返回该对象的默认遍历器。

2 iterator(遍历器)

js中有4种数据集合: Array、Object、Map、Set。数据结构又可以组合使用。所以需要统一的接口接口机制来处理不同的数据结构。

2.1 定义

iterator就是这样一种接口机制,任何数据结构只要部署了iterator接口,就能完成遍历操作既一次处理该数据结构的所有成员。

除了提供统一的访问接口,还能使得数据结构的成员能按某种次序排列。
同时也主要供 for…of(ES6新增的遍历命令)循环消费。

iterator的遍历过程如下:
1.创建一个指针对象,指向数据结构的起始位置。
2.调用指针对象的next方法,指针将指到第一个成员。并且返回信息,包含value和done两个属性的对象。
3.继续调用指针的next方法,指针指向数据结构的第二个成员。
依次调用,直到数据结构的结束位置。

2.2 默认接口

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内

2.3 原生具备 Iterator 接口的数据结构

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

如:

  1. let arr = ['a', 'b', 'c'];
  2. let iter = arr[Symbol.iterator]();
  3. iter.next() // { value: 'a', done: false }
  4. iter.next() // { value: 'b', done: false }
  5. iter.next() // { value: 'c', done: false }
  6. iter.next() // { value: undefined, done: true }

对于原生部署 Iterator 接口的数据结构,不用自己写遍历器生成函数,for...of循环会自动遍历它们

2.4 for / forEach / for in/ for of 区别

参考:https://www.bookstack.cn/read/es6-3rd/spilt.7.docs-iterator.md
语雀内容