我在网上找到了一些代码。我将原始代码压缩成这个小摘录,当运行时,将1-20打印到控制台。
var NumbersFromOne = {
*[Symbol.iterator] () {
for (let i = 1;; ++i) yield i;
}
};
var take = function* (numberToTake, iterable) {
let remaining = numberToTake;
for (let value of NumbersFromOne) {
if (remaining-- <= 0) break;
yield value;
}
}
var printToTwenty = take(20, NumbersFromOne)
console.log(...printToTwenty);
现在,我知道take()是一个GeneratorFunction 调用take()时,会给它一个迭代器 代码&#34; ... printToTwenty&#34;使用spread运算符迭代该函数。
我知道NumbersFromOne是一个对象。 我来这里寻找这部分含义的解释:
*[Symbol.iterator] () {}
声明生成器函数如下所示:function *(){}
所以我假设这不是声明生成器函数。
*也不代表功能名称
*也不能用其他运算符替换(/, - ,+)
该语法有什么处理,为什么在[Symbol.iterator]之前是*
如果放在后面,它将无法运行。
我曾经认为* [Symbol.iterator]()是一种覆盖现有迭代器属性的方法,但是它不会说这个[Symbol.iterator]。
谢谢!
答案 0 :(得分:16)
有些事情可能会使这段代码变得复杂:
它使用object属性简写表示法。您在这里看到的实际上是以下内容:
var NumbersFromOne = {
[Symbol.iterator]: function* () {
for (let i = 1;; ++i) yield i;
}
};
Symbol.iterator
为您NumbersFromOne
对象创建自定义迭代器。
所以你的代码基本上意味着NumbersFromOne
的迭代器被定义为生成器。而不是手动定义一个返回下一个和其他属性的函数:
var NumbersFromOne = {
[Symbol.iterator]: function () {
var i = 1;
return {
next: function() {
return { value: i++, done: false };
}
};
}
};
返回生成器会自动为您创建next
函数,并允许您在需要时生成。
然后可以将其命名为:
const it = NumbersFromOne[Symbol.iterator]();
it.next(); // 1
it.next(); // 2
it.next(); // 3
// ...
注意:以这种方式编写,这个迭代器永远不会结束,所以如果你在没有结束条件的for ... of
循环中调用它,它会冻结你的程序。