扩展运算符如何使用 Javascript 中的迭代器/生成器从对象获取值?

Gol*_*mba 1 javascript iterator generator spread

我有以下定义数组的代码,然后带有生成器的迭代器对象从该数组中生成值,并使用扩展运算符输出每个值:

\n
const arr = ['0', '1', '4', 'a', '9'];\nconst my_obj = {\n  [Symbol.iterator]: function*() {\n    for(let index of arr) {\n      yield `${index}`;\n    }\n  }\n};\n\nconst all = [...my_obj] \n\nconsole.log(...my_obj)\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
0\n1\n4\na\n9\n
Run Code Online (Sandbox Code Playgroud)\n

我不明白\xe2\x80\x99t 的是扩展运算符变量\xe2\x80\x9c...my_obj\xe2\x80\x9d 如何获取数组的值如果\xe2\x80\x9cmy_obj\xe2\x80 \x9d 是一个对象,而不是数组。据我了解: \xe2\x80\x9cmy_obj\xe2\x80\x9d 正在接收一个对象,如果应用扩展运算符,它应该得到 \xe2\x80\x9ckey:value\xe2\x80\x9d。

\n

有人能解释一下它是如何获得这些值的吗?

\n

Emi*_*ier 8

扩展运算符和for...of语句调用对象的可迭代协议。一些对象,如ArrayStringSetMap内置了可迭代协议。这意味着他们有这个@@iterator方法。

\n

您自己刚刚创建了一个对象并赋予了它一个属性[Symbol.iterator]。现在,您的对象知道在该对象上调用展开语法时要做什么for...of,即调用此迭代器并循环遍历由键中的生成器函数创建的可迭代对象[Symbol.iterator]

\n

在生成器函数中,您已指定在每次迭代时应生成 的值,arr直到循环完成。

\n

MDN在这里展示了一个示例,其中写道:

\n
\n

一些内置构造\xe2\x80\x94(例如扩展语法\xe2\x80\x94)在底层使用相同的迭代协议:\nconsole.log([...someString]); // ["h", "i"]

\n
\n

有时您会看到的一种模式是对象具有values方法。大多数时候这实际上是一个生成器函数。当[Symbol.iterator]调用时,它返回生成器函数,然后循环遍历对象中的值。

\n

在这里,我创建了一个小演示,它接受一个字符串并循环遍历字母,并使用扩展for...of运算符将它们布局。将调用一个生成器函数来查找每个字母在字母表中的位置。两者都使用相同的可迭代协议。[Symbol.iterator]

\n

\r\n
\r\n
class LettersObjects {\n\n  *values() {\n    // Here we use the iterable protocol of a string.\n    for (const letter of this.letters) {\n      const position = this.alphabet.indexOf(letter.toLowerCase()) + 1;\n      yield position.toString().padStart(2, \'0\');\n    }\n  }\n\n  // This is called with for...of and ...spread.\n  [Symbol.iterator]() {\n    return this.values();\n  }\n  \n  constructor(letters) {\n    this.letters = letters;\n    this.alphabet = \'abcdefghijklmnopqrstuvwxyz\';\n  }\n  \n}\n\nconst letters = new LettersObjects(\'Hello world\');\n\n// Call the iterable protocol on our LetterObjects instance.\nfor (const letter of letters) {\n  console.log(\'loop:\', letter);\n}\n\n// Call the iterable protocol on our LetterObjects instance.\nconsole.log(\'Spread:\', ...letters);
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n