javascript - 扩展运算符如何使用 Javascript 中的迭代器/生成器从对象中获取值?
问题描述
我有以下一段代码定义了一个数组,然后一个带有生成器的迭代器对象从这个数组中产生值,然后我用扩展运算符输出每个值:
const arr = ['0', '1', '4', 'a', '9'];
const my_obj = {
[Symbol.iterator]: function*() {
for(let index of arr) {
yield `${index}`;
}
}
};
const all = [...my_obj]
console.log(...my_obj)
结果是:
0
1
4
a
9
我不明白的是,如果“my_obj”是一个对象,而不是一个数组,则扩展运算符变量“...my_obj”如何获取数组的值。据我了解:“my_obj”正在接收一个对象,如果您应用扩展运算符,它应该得到“key:value”。
有人可以解释它是如何获得这些值的吗?
解决方案
扩展运算符和for...of
语句调用对象的可迭代协议。一些对象,如Array
, String
,Set
并Map
内置了可迭代的协议。这意味着他们有@@iterator
方法。
您自己刚刚创建了一个对象并为其赋予了[Symbol.iterator]
. 现在你的对象知道当for...of
在这个对象上调用扩展语法时要做什么,也就是调用这个迭代器并循环一个由[Symbol.iterator]
键中的生成器函数创建的可迭代对象。
并且在您的生成器函数中,您已经指定在每次迭代中arr
都应该产生一个值,直到该循环完成。
MDN在这里展示了一个例子,它说:
一些内置结构(例如扩展语法)在底层使用相同的迭代协议:
console.log([...someString]); // ["h", "i"]
有时你会看到一个模式是一个对象有一个values
方法。大多数时候,这实际上是一个生成器函数。当[Symbol.iterator]
调用它时,它返回生成器函数,然后循环对象中的值。
在这里,我创建了一个小演示,它接收一个字符串并循环遍历字母并使用扩展for...of
运算符将它们布局。将调用一个生成器函数来查找每个字母在字母表中的位置。两者都使用相同的可迭代协议。[Symbol.iterator]
class LettersObjects {
*values() {
// Here we use the iterable protocol of a string.
for (const letter of this.letters) {
const position = this.alphabet.indexOf(letter.toLowerCase()) + 1;
yield position.toString().padStart(2, '0');
}
}
// This is called with for...of and ...spread.
[Symbol.iterator]() {
return this.values();
}
constructor(letters) {
this.letters = letters;
this.alphabet = 'abcdefghijklmnopqrstuvwxyz';
}
}
const letters = new LettersObjects('Hello world');
// Call the iterable protocol on our LetterObjects instance.
for (const letter of letters) {
console.log('loop:', letter);
}
// Call the iterable protocol on our LetterObjects instance.
console.log('Spread:', ...letters);
推荐阅读
- javascript - http fetch 提供与网络不同的状态?
- java - 如何将来自互联网的视频文件设置为 Flutter 中的系统壁纸
- linux - 我正在尝试使用 CentOS 从 Linux 中的 CSV 添加多个用户
- c# - 相同的 Web API 代码适用于 Windows 10,但不适用于 Linux Debian Buster
- javascript - TypeError:在未实现接口 WebSocket 的对象上调用了“get binaryType”
- yaml - 提取与 YAML 中的正则表达式与布尔值匹配的键值对
- google-app-engine - 为什么 gcloud 出错后我的任务没有留在队列中?
- python - 使用 PySpark 将列表列表传播到 Sparks DF?
- django - 在 docker 生产环境中文件写入失败
- graphql - Graphql 按查询过滤