1、ES6实现的是为迭代器引入一个隐式的标准化接口。
2、为了达到最大化的互操作性,也可以自己构建符合这个标准的迭代器。
3、迭代器是一种有序的、连续的、基于拉取的用于消耗数据的组织方式。
4、接口
Iterator [required]
next() {method}: 取得下一个IteratorResult
Iterator [optional]
return () {method} : 停止迭代器并返回IteratorResult
throw() {method} :报错并返回IteratorResult
IteratorResult 接口指定如下
IteratorResult
value {property} : 当前迭代值或者最终返回值(如果undefined为可选的)
done {property} : 布尔值,指示完成状态
IteratorResult 接口指定了从任何迭代器操作返回的值必须是下面这种形式的对象: { value: .., done: true / false } Iterable
@@iterator() {method} : 产生一个 Iterator
@@iterator是一个特殊的内置符号,表示可以为这个对象产生迭代器的方法
5、next() 迭代
next()调用越过数组结尾的值,才能得到完成信号 done: true。
var arr = [1,2,3]; var it = arr[Symbol.iterator](); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next()); 结果:
{ value: 1, done: false } { value: 2, done: false } { value: 3, done: false } { value: undefined, done: true } var greeting = 'Hello world'; var it = greeting[Symbol.iterator](); console.log(it.next()); console.log(it.next()); console.log(it.next()); 结果:
{ value: 'H', done: false } { value: 'e', done: false } { value: 'l', done: false } var m = new Map(); m.set('foo', 42); m.set({cool:true}, 'Hello world'); var it1 = m[Symbol.iterator](); var it2 = m.entries(); console.log(it1.next()); console.log(it1.next()); console.log(it2.next()); console.log(it2.next()); 结果;
{ value: [ 'foo', 42 ], done: false } { value: [ { cool: true }, 'Hello world' ], done: false } { value: [ 'foo', 42 ], done: false } { value: [ { cool: true }, 'Hello world' ], done: false } 8、
// 构造一个迭代器来产生一个无线斐波那契数列 var Fib = { [Symbol.iterator]() { var n1 = 1, n2 = 1; return { // 使迭代器成为iterable [Symbol.iterator]() { return this; }, next () { var current = n2; n2 = n1; n1 = n1 + current; return { value: current, done: false } }, return (v) { console.log("Fibonacci sequence abandoned"); return { value: v, done: true } } } } } for(var v of Fib){ console.log(v); if(v > 50){ break; } } 9、
// 循环条目 // 使tasks成为iterable var tasks = { [Symbol.iterator]() { var steps = this.actions.slice(); return { [Symbol.iterator]() { return this; }, next(...args){ if (steps.length > 0) { let res = steps.shift(...args); return { value: res, done: false } } else { return { done: true } } }, return(v) { steps.length = 0; return { value: v, done: true } } } }, actions: [] } tasks.actions.push( function step1(x) { console.log("step1:", x); return x * 2; }, function step2(x,y) { console.log("step2:", x, y); return x + ( y * 2 ); }, function step3(x,y,z) { console.log("step3:", x, y, z); return (x * y) + z; }, ); var it = tasks[Symbol.iterator](); it.next(10); it.next(10, 50); it.next(10, 50, 120); it.next(); 10、自定义迭代器表示单个数据上的元操作
if (!Number.prototype[Symbol.iterator]) { Object.defineProperty( Number.prototype, Symbol.iterator, { writable: true, configurable: true, enumerable: false, value: function iterator() { var i, inc, done = false, top = +this; // 正向还是反向迭代 inc = 1 * (top < 0 ? -1 : 1); return { // 使得迭代器本身成为iterable [Symbol.iterator]() { return this;}, next () { if(!done) { // 初始迭代总是0 if (i == null){ i = 0; } // 正向迭代 else if(top >= 0){ i = Math.min(top, i + inc); } // 反向迭代 else { i = Math.max(top, i + inc); } // 本次迭代后结束 if (i == top) { done = true; } return { value: i, done: false } } else { return { done: true } } } } } } ); } for ( var i of 3){ console.log(i); } console.log([...3]) 转载请标明出处:ES6 迭代器
文章来源: ES6 迭代器