Javascript 在此上下文中,*[Symbol.iterator]的含义是什么

Javascript 在此上下文中,*[Symbol.iterator]的含义是什么,javascript,Javascript,我在网上找到了一些代码。我已经将原始代码压缩到这个小摘录中,当运行它时,将向控制台打印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 NumbersFr

我在网上找到了一些代码。我已经将原始代码压缩到这个小摘录中,当运行它时,将向控制台打印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);
声明生成器函数的方式如下:函数*(){}
所以我假设这不是声明一个生成函数

*也不代表函数名
*也不能替换为另一个运算符(/,-,+)

该语法的处理方法是什么?为什么在[Symbol.iterator]前面加*号
如果放在后面,它将不会运行
我曾经考虑过*[Symbol.iterator]()是覆盖现有迭代器属性的一种方法,但是它不会说这个[Symbol.iterator]


谢谢

有几件事可能会让这段代码看起来很复杂:

它使用对象属性速记符号。您在这里看到的实际上是以下内容:

var NumbersFromOne = {
  [Symbol.iterator]: function* () {
    for (let i = 1;; ++i) yield i;
  }
};
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
// ...

注意:以这种方式编写,迭代器永远不会结束!所以如果你在一个
中调用它。。。如果循环没有结束条件,它将冻结您的程序。

我喜欢这个答案。我想指出的是,*必须在函数后面。我制作了一个jsfiddle来演示:我不知道这是一个简写符号。谢谢你的澄清哎呀,我的错,谢谢你指出这一点。我还没有机会写那么多真实世界的生成器。现在它应该可以工作了:)嘿,尼尔斯-为什么这里需要两个迭代器,取&numbersfromone。如果你能从1中得到一个数字范围,Take似乎是多余的,不是吗?嘿,James,
Take
不是我答案的一部分。它只是提供了一个多余的迭代层。我也看不出使用它的理由。@nils我刚才在代码段中看到了
Symbol.iterator
的用法。但我不明白为什么在那里用。代码正在使用迭代器对对象数组进行迭代,但我认为没有任何理由不使用
for循环
。有什么区别?演出
const it = NumbersFromOne[Symbol.iterator]();
it.next(); // 1
it.next(); // 2
it.next(); // 3
// ...