JavaScript中的迭代器和生成器详解_javascript技巧
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JavaScript中的迭代器和生成器详解_javascript技巧,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4759字,纯文字阅读大概需要7分钟。
内容图文
![JavaScript中的迭代器和生成器详解_javascript技巧](/upload/InfoBanner/zyjiaocheng/323/8fe34f76a3864f5891eab7a40859245d.jpg)
迭代器
迭代器是一个每次访问集合序列中一个元素的对象,并跟踪该序列中迭代的当前位置。在JavaScript中迭代器是一个对象,这个对象提供了一个 next() 方法,next() 方法返回序列中的下一个元素。当序列中所有元素都遍历完成时,该方法抛出 StopIteration 异常。
迭代器对象一旦被建立,就可以通过显式的重复调用next(),或者使用JavaScript的 for…in 和 for each 循环隐式调用。
简单的对对象和数组进行迭代的迭代器可以使用 Iterator() 被创建:
var lang = { name: 'JavaScript', birthYear: 1995 };
var it = Iterator(lang);
一旦初始化完成,next() 方法可以被调用来依次访问对象的键值对:
var pair = it.next(); //键值对是["name", "JavaScript"]
pair = it.next(); //键值对是["birthday", 1995]
pair = it.next(); //一个 `StopIteration` 异常被抛出
for…in 循环可以被用来替换显式的调用 next() 方法。当 StopIteration 异常被抛出时,循环会自动终止。
var it = Iterator(lang);
for (var pair in it)
print(pair); //每次输出 it 中的一个 [key, value] 键值对
如果你只想迭代对象的 key 值,可以往 Iterator() 函数中传入第二个参数,值为 true:
var it = Iterator(lang, true);
for (var key in it)
print(key); //每次输出 key 值
使用 Iterator() 访问对象的一个好处是,被添加到 Object.prototype 的自定义属性不会被包含在序列对象中。
Iterator() 同样可以被作用在数组上:
var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterator(langs);
for (var pair in it)
print(pair); //每次迭代输出 [index, language] 键值对
就像遍历对象一样,把 true 当做第二个参数传入遍历的结果将会是数组索引:
var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterator(langs, true);
for (var i in it)
print(i); //输出 0,然后是 1,然后是 2
使用 let 关键字可以在循环内部分别分配索引和值给块变量,还可以解构赋值(Destructuring Assignment):
var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterators(langs);
for (let [i, lang] in it)
print(i + ': ' + lang); //输出 "0: JavaScript" 等
声明自定义迭代器
一些代表元素集合的对象应该用一种指定的方式来迭代。
1.迭代一个表示范围(Range)的对象应该一个接一个的返回这个范围包含的数字
2.一个树的叶子节点可以使用深度优先或者广度优先访问到
3.迭代一个代表数据库查询结果的对象应该一行一行的返回,即使整个结果集尚未全部加载到一个单一数组
4.作用在一个无限数学序列(像斐波那契序列)上的迭代器应该在不创建无限长度数据结构的前提下一个接一个的返回结果
JavaScript 允许你写自定义迭代逻辑的代码,并把它作用在一个对象上
我们创建一个简单的 Range 对象,包含低和高两个值:
function Range(low, high){
this.low = low;
this.high = high;
}
现在我们创建一个自定义迭代器,它返回一个包含范围内所有整数的序列。迭代器接口需要我们提供一个 next() 方法用来返回序列中的下一个元素或者是抛出 StopIteration 异常。
function RangeIterator(range){
this.range = range;
this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
if (this.current > this.range.high)
throw StopIteration;
else
return this.current++;
};
我们的 RangeIterator 通过 range 实例来实例化,同时维持一个 current 属性来跟踪当前序列的位置。
最后,为了让 RangeIterator 可以和 Range 结合起来,我们需要为 Range 添加一个特殊的 __iterator__ 方法。当我们试图去迭代一个 Range 时,它将被调用,而且应该返回一个实现了迭代逻辑的 RangeIterator 实例。
Range.prototype.__iterator__ = function(){
return new RangeIterator(this);
};
完成我们的自定义迭代器后,我们就可以迭代一个范围实例:
var range = new Range(3, 5);
for (var i in range)
print(i); //输出 3,然后 4,然后 5
生成器:一种更好的方式来构建迭代器
虽然自定义的迭代器是一种很有用的工具,但是创建它们的时候要仔细规划,因为需要显式的维护它们的内部状态。
生成器提供了很强大的功能:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。
生成器是可以作为迭代器工厂的特殊函数。如果一个函数包含了一个或多个 yield 表达式,那么就称它为生成器(译者注:Node.js 还需要在函数名前加 * 来表示)。
注意:只有 HTML 中被包含在 输出 "first"
print(g.next()); //输出 "second"
print(g.next()); //输出 "third"
print(g.next()); //输出 0
print(g.next()); //输出 1
print(g.next()); //输出 2
print(g.next()); //抛出 StopIteration 异常
内容总结
以上是互联网集市为您收集整理的JavaScript中的迭代器和生成器详解_javascript技巧全部内容,希望文章能够帮你解决JavaScript中的迭代器和生成器详解_javascript技巧所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。