js 可迭代对象,迭代器和迭代对象
迭代是访问集合元素的一种方式;可以迭代的对象称为可迭代对象;迭代器是一个可以记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有元素都被访问。迭代器只能向前,不能向后。
Lazy evaluation
惰性求值通常被翻译为“延迟计算”或“惰性计算”,意思是表达式的值只有在真正需要执行时才被计算。
与懒求值相反,热切求值,也称为贪婪求值或严格求值,是大多数传统编程语言的求值策略。
充分利用懒评的好处主要体现在以下两个方面:
避免不必要的计算并提高性能。
节省空间,并使无限循环数据结构成为可能。
迭代器
ES6中的迭代器使得延迟求值和创建用户定义的数据序列成为可能。迭代是一种遍历数据的机制。迭代器是用来遍历数据结构元素(称为Iterable)的指针,也是用来生成值序列的指针。
迭代器是可以被迭代的对象。它抽象了数据容器,使其行为类似于可迭代对象的行为。
迭代器在实例化时不计算每一项的值,只在请求时生成下一个值。这非常有用,尤其是对于大型数据集或无限元素序列。
可迭代对象
迭代对象是其元素预期可被公众访问的数据结构。JS中的很多对象都是迭代的。它们可能没有被很好地感知,但是如果你仔细检查它们,你会发现迭代的特征:
新地图([可重复])
新的weak map([可重复])
新集合([可迭代])
新武器集([可重复])
Promise.all([iterable])
Promise.race([iterable])
Array.from([iterable])
还需要一个iterable对象,否则会抛出类型错误,比如:
为.关于
.(扩展运算符)
常数[a,b,]=iterable(解构赋值)
产量*(发电机)
JavaScript中有许多内置迭代:
字符串,数组,类型数组,映射,集合.
迭代协议
迭代器和重叠对象遵循迭代协议。
迭代器遵循迭代器协议,迭代遵循迭代协议。
可迭代的协议
要使对象迭代,它必须通过Symbol.iterator实现迭代器方法,这是迭代器的工厂。
对于TypeScript,迭代协议如下:
接口可迭代{
[Symbol.iterator]():迭代器;
}Symbol.iterator]()是一个无参数函数。在iterable对象上调用它,也就是说我们可以通过这个来访问iterable对象,这个对象可以是常规函数,也可以是生成器函数。
迭代器协议
迭代器协议定义了生成值序列的标准方法。
为了使一个对象成为迭代器,它必须实现next()方法。迭代器可以实现return()方法,我们将在本文后面讨论。
对于TypeScript,迭代器协议如下:
接口迭代器{
next():iterator result;
回归?(值?any):iterator result;
}IteratorResult定义如下:
接口迭代结果{
价值?任何;
done:boolean;
}done通知消费者迭代器是否已被使用。false表示还有值要生成,true表示迭代器已经结束。
Value可以是任何JS值,这是显示给消费者的值。
当done为true时,可以省略value。
组合
迭代器和可以迭代的对象可以用下图表示:
事例
基础知识已经介绍过了。接下来,我们用一些例子来加深我们的形象。
范围迭代器
让我们从一个非常基本的迭代器开始,createRangeIterator迭代器。
我们手动调用它. next()来获取下一个IteratorResult。最后一次调用返回{done: true},这意味着迭代器现在已经被使用,不再产生任何值。
函数createRangeIterator(from,to) {
设i=from
返回{
下一个(){
if (i=to) {
return { value: i,done:false };
}否则{
返回{ done:true };
}
}
}
}
const it=createRangeIterator(1,3);
console . log(it . next());
console . log(it . next());
console . log(it . next());
console . log(it . next());
可迭代范围迭代器
在本文前面,我提到过JS中的一些语句需要一个iterable对象。因此,当与for一起使用时,我们前面的示例将不起作用.循环的。
但是创建符合迭代器和迭代协议的对象是非常容易的。
函数createRangeIterator (from,to) {
让我=从
返回{
[Symbol.iterator] () {
归还这个
},
下一个(){
if (i=to) {
return { value: i,done: false }
}否则{
返回{ done: true }
}
}
}
}
const it=createRangeIterator(1,3)
对于(const i of it) {
console.log(i)
}
无限序列迭代器
迭代器可以表示无限大小的序列,因为它们只在需要的时候计算值。
注意不要使用扩展运算符(.)在无限迭代器上。JS会尝试消耗迭代器,由于迭代器是无限的,所以永远不会结束。所以你的应用程序会因为内存耗尽而崩溃。
同样,for也是如此.的循环,所以确保可以退出循环:
函数createEvenNumbersIterator () {
让值=0
返回{
[Symbol.iterator] () {
归还这个
},
下一个(){
值=2
返回{ value,done: false}
}
}
}
const it=createevenumbersiterator()
const [a,b,c]=it
console.log({a,b,c})
const [x,y,z]=it
console.log({ x,y,z })
为(const even it){
console.log(偶数)
如果(甚至20) {
破裂
}
}
关闭迭代器
如前所述,迭代器可以有选择地使用return()方法。当迭代器直到末尾才迭代时使用这个方法,让迭代器清理。
森林.of循环可以通过以下方式提前终止迭代:
破裂
继续
扔
返回
函数createCloseableIterator () {
设idx=0
const data=[a , b , c , d , e]
函数清理(){
console.log(执行清理)
}
返回{
[Symbol.iterator]() {返回此},
下一个(){
if (idx=data.length - 1) {
返回{ value: data[idx ],done: false }
}否则{
清理()
返回{ done: true }
}
},
return()
清理()
返回{ done: true }
}
}
}
const it=createCloseableIterator()
for(它的常数值){
console.log(值)
if (value===c) {
破裂
}
}
console.log(\n - \n )
const _ it=createCloseableIterator();
for(it的常数值){
console.log(值);
}
如果知道迭代器已经结束,手动调用cleanup()函数。
如果它突然结束,return()会工作并为我们清理。
【推荐学习:javascript高级教程】以上是JavaScript中迭代器和迭代器的详细内容。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。