gpt4 book ai didi

javascript - 为什么 Javascript `iterator.next()` 返回一个对象?

转载 作者:数据小太阳 更新时间:2023-10-29 05:11:24 25 4
gpt4 key购买 nike

帮助!在用 C# 编程了很长一段时间后,我开始喜欢上 Javascript,但我一直在学习喜欢可迭代协议(protocol)!

为什么 Javascript 采用 protocol需要为每次迭代创建一个新对象?为什么有next()返回一个属性为 done 的新对象和 value而不是采用像 C# IEnumerable 这样的协议(protocol)和 IEnumerator它以需要两次调用为代价不分配任何对象(一次调用 moveNext 以查看迭代是否完成,第二次调用 current 以获取值)?

是否有底层优化跳过由 next() 返回的对象的分配? ?很难想象,因为 iterable 不知道返回后如何使用该对象...

生成器似乎不会重用下一个对象,如下所示:

function* generator() {
yield 0;
yield 1;
}

var iterator = generator();
var result0 = iterator.next();
var result1 = iterator.next();

console.log(result0.value) // 0
console.log(result1.value) // 1

嗯,here's一条线索(感谢 Bergi!):

We will answer one important question later (in Sect. 3.2): Why can iterators (optionally) return a value after the last element? That capability is the reason for elements being wrapped. Otherwise, iterators could simply return a publicly defined sentinel (stop value) after the last element.

在 Sect. 3.2 他们讨论使用Using generators as lightweight threads .似乎说了从 next 返回对象的原因是这样一个 value即使在 done 时也可以返回是true !哇。此外,发电机可以 return除了 yield 之外的值和 yield* -ing 值和由 return 生成的值最终如 value什么时候donetrue !

所有这些都允许伪线程。而这个特性,伪线程,值得为每次循环分配一个新对象......Javascript。总是那么出乎意料!


虽然,现在我想想,允许yield* “返回”一个值以启用伪线程仍然不能证明返回一个对象是合理的。 IEnumerator可以扩展协议(protocol)以在 moveNext() 之后返回一个对象返回 false -- 只需添加一个属性 hasCurrent在迭代完成后测试 true表示 current具有有效值...

并且编译器优化非常重要。这将导致迭代器的性能出现相当大的差异……这不会给库实现者带来问题吗?

所有这些要点都在 this thread 中提出由友好的 SO 社区发现。然而,这些论点似乎并没有站住脚。


但是,无论是否返回对象,都不会在迭代“完成”后检查值,对吗?例如。大多数人会认为以下将记录迭代器返回的所有值:

function logIteratorValues(iterator) {
var next;
while(next = iterator.next(), !next.done)
console.log(next.value)
}

除了它不是因为即使 donefalse迭代器可能仍然返回了另一个值。考虑:

function* generator() {
yield 0;
return 1;
}

var iterator = generator();
var result0 = iterator.next();
var result1 = iterator.next();

console.log(`${result0.value}, ${result0.done}`) // 0, false
console.log(`${result1.value}, ${result1.done}`) // 1, true

在“完成”后返回值的迭代器真的是迭代器吗?一只手拍手的声音是什么?这看起来很奇怪......


here是关于我喜欢的发电机的深度帖子。很多时间花在控制应用程序的流程上,而不是迭代集合的成员。


另一种可能的解释是 IEnumerable/IEnumerator 需要两个接口(interface)和三个方法,而 JS 社区更喜欢单一方法的简单性。这样他们就不必引入符号方法组的概念,也就是接口(interface)......

最佳答案

Are there under-the-hood optimizations that skip the allocation of the object return by next()?

是的。这些迭代器结果对象很小,而且通常是短暂的。特别是在 for … of 循环中,编译器可以进行简单的逃逸分析,以查看对象根本不面向用户代码(但仅面向内部循环评估代码)。它们可以被垃圾收集器非常有效地处理,甚至可以直接在堆栈上分配。

以下是一些来源:

关于javascript - 为什么 Javascript `iterator.next()` 返回一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53894639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com