ES6 迭代器

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])

猜你喜欢

转载自blog.csdn.net/wuweitiandian/article/details/80719513