2017-07-30 103 views
0

在笔记它指出:理解迭代器协议

迭代协议允许JavaScript对象定义或定制 他们的迭代行为,比如什么值在 for..of挂绕构造。

当我已经可以使用Object.degineProperty来使某些东西可枚举时,我看不出有什么好处。

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

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

+0

属性的可枚举性与迭代器完全无关?最重要的是,属性没有**顺序**,在其中进行迭代。 – Bergi

+0

迭代器比“列表”更通用。它甚至不需要有一个长度 - 如果你想要它可以是无限的! – Bergi

+0

“*在说明中注明*” - 什么?哪里?哪些笔记? – Bergi

回答

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接口,同变得非常简单:你可以用Iterables做什么

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]; 
     } 
    } 
} 

更多的例子列出here

+0

'count'应该在迭代器中声明 – Bergi