前端JavaScript基础训练系列一百八十二:iterable

next() 调用返回一个对象。这个对象有两个属性:done 是一个 boolean 值,标识迭代器的 完成状态;value 中放置迭代值。
ES6 还新增了一个 for…of 循环,这意味着可以通过原生循环语法自动迭代标准迭代器:

for (var v of something) {
         console.log( v );
// 不要死循环! if (v > 500) {
break; }
     }

因为我们的迭代器 something 总是返回 done:false,因此这个 for…of 循环 将永远运行下去,这也就是为什么我们要在里面放一个 break 条件。迭代器 永不结束是完全没问题的,但是也有一些情况下,迭代器会在有限的值集合 上运行,并最终返回 done:true。

for…of 循环在每次迭代中自动调用 next(),它不会向 next() 传入任何值,并且会在接收 到 done:true 之后自动停止。这对于在一组数据上循环很方便。
当然,也可以手工在迭代器上循环,调用 next() 并检查 done:true 条件来确定何时停止循 环:

for (
var ret;
(ret = something.next()) && !ret.done; ){
         console.log( ret.value );
// 不要死循环!
if (ret.value > 500) {
break; }
     }

这种手工 for 方法当然要比 ES6 的 for…of 循环语法丑陋,但其优点是,这 样就可以在需要时向 next() 传递值。
除了构造自己的迭代器,许多 JavaScript 的内建数据结构(从 ES6 开始),比如 array,也 有默认的迭代器:

var a = [1,3,5,7,9];
     for (var v of a) {
         console.log( v );
}
// 1 3 5 7 9

for…of 循环向 a 请求它的迭代器,并自动使用这个迭代器迭代遍历 a 的值。
这里可能看起来像是 ES6 一个奇怪的缺失,不过一般的 object 是故意不 像 array 一样有默认的迭代器。这里我们并不会深入探讨其中的缘由。如 果你只是想要迭代一个对象的所有属性的话(不需要保证特定的顺序),可 以通过Object.keys(…)返回一个array,类似于for (var k of Object. keys(obj)) { …这样使用。这样在一个对象的键值上使用for…of循环与 for…in 循环类似,除了 Object.keys(…) 并不包含来自于 [[Prototype]] 链 上的属性,而 for…in 则包含。

iterable

前面例子中的 something 对象叫作迭代器,因为它的接口中有一个 next() 方法。而与其紧
密相关的一个术语是 iterable(可迭代),即指一个包含可以在其值上迭代的迭代器的对象。
从 ES6 开始,从一个 iterable 中提取迭代器的方法是:iterable 必须支持一个函数,其名称 是专门的 ES6 符号值 Symbol.iterator。调用这个函数时,它会返回一个迭代器。通常每 次调用会返回一个全新的迭代器,虽然这一点并不是必须的。
前面代码片段中的 a 就是一个 iterable。for…of 循环自动调用它的 Symbol.iterator 函数来 构建一个迭代器。我们当然也可以手工调用这个函数,然后使用它返回的迭代器:

    var a = [1,3,5,7,9];
     var it = a[Symbol.iterator]();
 it.next().value;
it.next().value;
it.next().value;
..
// 1 // 3 // 5

前面的代码中列出了定义的 something,你可能已经注意到了这一行: [Symbol.iterator]: function(){ return this; }
这段有点令人疑惑的代码是在将 something 的值(迭代器 something 的接口)也构建成为一 个 iterable。现在它既是 iterable,也是迭代器。然后我们把 something 传给 for…of 循环:

for (var v of something) {
         ..
}

for…of 循环期望 something 是 iterable,于是它寻找并调用它的 Symbol.iterator 函数。 我们将这个函数定义为就是简单的 return this,也就是把自身返回,而 for…of 循环并 不知情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值