15.1 Iterator(遍历器)的概念
Iterator 的遍历如下:
1. 创建一个指针对象, 指向当前数据结构的其实位置。也就是说, 遍历器对象本质上就是一个指针对象。
2.第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
3.第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
4.不断调用指针对象的next方法,直到它指向数据结构的结束为止。
var it = makeIterator(['a', 'b']);
it.next();
it.next();
it.next();
function makeIterator(array) {
var nextIndex = 0;
return {
next: function () {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false}:
{value: undefined, done: true};
}
}
}
var it = idMaker();
it.next().value;
it.next().value;
it.next().value;
function idMaker() {
var index = 0;
return {
next: function () {
return {value: index++, done: false};
}
}
}
15.2
const obj = {
[Symbol.iterator]: function () {
return {
next: function () {
return {
value: 1,
done: true
}
}
}
}
}
原生具备 Iterator 接口的数据结构如下
1. Array
2. Map
3. Set
4. String
5. TypedArray
6. 函数的arguments对象。
7. NodeList 对象
let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]()
iter.next();
iter.next();
iter.next();
iter.next();
class RangeIterator {
constructor (start, stop) {
this.value = start;
this.stop = stop;
}
[Symbol.iterator]() {return this;}
next() {
var value = this.value;
if(value < this.stop) {
this.value++;
return {done: false, value: value}
}
return {done: true, value: undefined}
}
}
function range(start, stop) {
return new RangeIterator(start, stop);
}
for(var value of range(0, 3)) {
console.log(value);
}
function Obj(value) {
this.value = value;
this.next = null;
}
Obj.prototype[Symbol.iterator] = function () {
var iterator = {next: next};
var current = this;
function next () {
if(current) {
var value = current.value;
current = current.next;
return {done: false, value: value};
} else {
return {done: true};
}
}
return iterator;
}
var one = new Obj(1);
var two = new Obj(2);
var three = new Obj(3);
one.next = two;
two.next = three;
for(var i of one) {
console.log(i);
}
let obj = {
data: ['hello', 'world'],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if(index < self.data.length) {
return {
value: self.data[index++],
done: false
};
} else {
return {value: undefined, done: true};
}
}
}
}
}
15.3
let set = new Set().add('a').add('b').add('c');
let [x, y] = set;
let [first, ...rest] = set
let generator = function* () {
yield 1;
yield* [2, 3, 4];
yield 5;
}
var iterator = generator();
iterator.next();
iterator.next();
iterator.next();
iterator.next();
iterator.next();
iterator.next();
15.4
var someString = "hi";
typeof someString[Symbol.iterator];
// "function"
var iterator = someString[Symbol.iterator];
iterator.next();
iterator.next();
iterator.next();
var str = new String("hi");
[...str] // ["h", "i"]
str[Symbol.iterator] = function () {
return {
next: function () {
if (this._first) {
this._first = false;
return {value: 'bye', done: false};
} else {
return {done: true};
}
}
, _first: true
}
}
[...str] // ['bye']
str //'hi'
15.5
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
{...myIterable}
// 或者采用下面的简介写法
let obj = {
* [Symbol.iterator]() {
yield 'hello';
yield 'world';
}
}
for(let x of obj) {
console.log(x);
}
15.7.1
const arr = ['red', 'green', 'blue'];
for(let v of arr) {
console.log(v);
}
const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);
for(let v of obj) {
console.log(v);
}
15.7.2
var engines = new Set(['Gecko', 'Trident', 'Webkit', 'Webkit']);
for (var e of engines) {
console.log(e);
}
var es6 = new Map();
es6.set('edition', 6);
es6.set('committee', 'TC39');
es6.set('standard', 'ECMA-262');
for (var [name, value] of es6) {
console.log(name + ': ' + value);
}