前端笔记

Iterator(迭代器)(数组、对象、Map、Set、Stri

2018-05-15  本文已影响1人  好奇男孩

iterator是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

iterator 的作用有三个:

Iterator 的遍历过程

var it = makeIterator(['a', 'b']);

it.next() // { value: "a" }
it.next() // { value: "b"}
it.next() // {  done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++]} :
        {done: true};
    }
  };
}
let myIterable = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
    yield 3;
  }
}
[...myIterable] // [1, 2, 3]

默认 Iterator 接口

原生具备 Iterator 接口的数据结构如下,即具有Symbol.iterator属性;

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();

iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }

有了遍历器接口,数据结构就可以用for...of循环遍历(详见下文),也可以使用while循环遍历。

调用 Iterator 接口的场合

一些场合会默认调用 Iterator 接口(即Symbol.iterator方法)

解构赋值

对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法。

let set = new Set().add('a').add('b').add('c');

let [x,y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
// first='a'; rest=['b','c'];

扩展运算符

扩展运算符(...)也会调用默认的 Iterator 接口

var str = 'hello';
[...str] //  ['h','e','l','l','o']
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']

只要某个数据结构部署了 Iterator 接口,就可以对它使用扩展运算符,将其转为数组

let arr = [...iterable];

yield*

yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口

let generator = function* () {
  yield 1;
  yield* [2,3,4];
  yield 5;
};

var iterator = generator();

iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }

其他

数组的遍历会调用遍历器接口,任何接受数组作为参数的场合,其实都调用了遍历器接口。

字符串的 Iterator 接口

var someString = "hi";
typeof someString[Symbol.iterator]
// "function"

var iterator = someString[Symbol.iterator]();

iterator.next()  // { value: "h", done: false }
iterator.next()  // { value: "i", done: false }
iterator.next()  // { value: undefined, done: true }

用Generator 函数 实现Iterator 接口

let myIterable = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
    yield 3;
  }
}
[...myIterable] // [1, 2, 3]

任意一个对象的Symbol.iterator方法,等于该对象的迭代器生成函数,调用该函数会返回该对象的一个迭代器对象。

上一篇下一篇

猜你喜欢

热点阅读