理解迭代器协议

时间:2017-07-30 08:15:27

标签: javascript ecmascript-6 iterator

在说明中说明:

  

iterable 协议允许JavaScript对象定义或自定义   它们的迭代行为,例如在a中循环的值   for..of construct。

当我已经可以使用时,我看不出它有什么好处:Object.degineProperty可以产生可枚举的东西。

function withValue(value) {
       var d = withValue.d || (
           withValue.d = {
               enumerable: false,
               writeable: false,
               configuration: false,
               value: null
          }
      )
    // other code;
   }

这些协议有哪些好处?如果这只是一个新的for语句来安抚循环的新语法,除了简单地检查长度并查看它是否用尽了“列表”中的项目之外,还有什么好处。

1 个答案:

答案 0 :(得分:1)

将Iterable视为一个界面。您可以放心,实现包含Symbol.iterator属性,该属性实现next()方法。如果您自己实现,则可以生成要在运行时迭代的值。举个简单的例子,生成一个列表,然后决定要迭代多少(或哪个或任何标准):

function List (...args) {
    this.getOnly = function (limit) (
        const effectiveLimit = Math.min(args.length, limit + 1);
        const iterable = {
            [Symbol.iterator]() {
                let count = 0;
                const iterator = {
                    next() {
                        if (count < effectiveLimit) {
                            return { value: args[count++] };
                        } else {
                            return { done: true };
                        }
                    }
                };
                return iterator;
            }
        }
        return iterable;
    };
}

const list = List(0, 1, 2, 3, 4);
for (const x of list.getOnly(3)) {
    console.log(x);
}
// returns 0, 1, 2

如果你使用一个实现Iterable接口的Generator函数,那么它就变得非常简单了:

function List (...args) {
    this.getOnly = function* (limit) {
        const effectiveLimit = Math.min(args.length, limit + 1);
        for (let count = 0; count < effectiveLimit; count++) {
            yield args[count];
        }
    }
}

有关Iterables可以执行的操作的更多示例,请列出here