如何把一个对象变成可迭代对象?
参考答案:
可迭代对象(Iterable object)是数组的泛化,这个概念是在说任何对象都可以被定制为可在 for..of 循环中使用的对象。
也就是说,可以应用 for..of 的对象被称为 可迭代对象。
迭代器
在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。
更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象:
value,这是序列中的next值done,如果已经迭代到序列中的最后一个值,则它为true
如果 value 和 done 一起存在,则它是迭代器的返回值。
一旦创建,迭代器对象可以通过重复调用 next() 显式地迭代。
迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。
在产生终止值之后,对 next() 的额外调用应该继续返回 {done: true}。
Javascript 中最常见的迭代器是 Array 迭代器,它只是按顺序返回关联数组中的每个值。
虽然很容易想象所有迭代器都可以表示为数组,但事实并非如此。数组必须完整分配,但迭代器仅在必要时使用,因此可以表示无限大小的序列,例如 0 和无穷大之间的整数范围。
这是一个可以做到这一点的例子。它允许创建一个简单的范围迭代器,它定义了从开始(包括)到结束(独占)间隔步长的整数序列。它的最终返回值是它创建的序列的大小,由变量 iterationCount 跟踪。
let index = 0
const bears = ['ice', 'panda', 'grizzly']
let iterator = {
next() {
if (index < bears.length) {
return { done: false, value: bears[index++] }
}
return { done: true, value: undefined }
}
}
console.log(iterator.next()) //{ done: false, value: 'ice' }
console.log(iterator.next()) //{ done: false, value: 'panda' }
console.log(iterator.next()) //{ done: false, value: 'grizzly' }
console.log(iterator.next()) //{ done: true, value: undefined }实现可迭代对象
如果一个对象拥有 [Symbol.iterator] 方法,并且该方法返回一个迭代器对象,这样的对象即可称为可迭代对象。
let info = {
bears: ['ice', 'panda', 'grizzly'],
[Symbol.iterator]: function() {
let index = 0
let _iterator = {
//这里一定要箭头函数,或者手动保存上层作用域的this
next: () => {
if (index < this.bears.length) {
return { done: false, value: this.bears[index++] }
}
return { done: true, value: undefined }
}
}
return _iterator
}
}
let iter = info[Symbol.iterator]()
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
//符合可迭代对象协议 就可以利用 for of 遍历
for (let bear of info) {
console.log(bear)
}
//ice panda grizzly题目要点:
在JavaScript中,一个普通的对象默认不是可迭代对象,因为它没有实现迭代器协议(即没有Symbol.iterator方法)。要使对象变得可迭代,你需要手动给该对象添加一个Symbol.iterator方法。
Symbol.iterator方法应该返回一个迭代器对象,该对象有一个next()方法,该方法返回一个对象,该对象包含value和done两个属性。value属性是当前迭代的值,done属性是一个布尔值,表示迭代是否完成。
可以通过几种方式来实现Symbol.iterator方法:
直接编写迭代器逻辑:在
Symbol.iterator方法中编写逻辑来逐个返回对象的属性或值。这通常涉及到维护一个内部状态(如索引或迭代器位置)来跟踪当前迭代的位置。使用生成器函数:生成器函数提供了一种更简洁的方式来编写迭代器。你可以使用
function*语法定义一个生成器函数,并在其中使用yield语句来逐个返回值。如果你想要迭代对象的属性或值,你可以结合使用Object.keys(),Object.values(), 或Object.entries()等方法来简化逻辑。委托迭代:如果你的对象包含另一个可迭代对象(如数组或另一个实现了
Symbol.iterator方法的对象),你可以在你的Symbol.iterator方法中简单地返回那个内部对象的迭代器。这可以通过使用yield*语句(在生成器函数中)来实现,它会委托迭代给另一个迭代器。