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 }
6、字符串也��
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 }
7、集合也��
扫描二维码关注公众号,回复:
1637307 查看本文章
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])