JS Iterator 迭代协议
程序员文章站
2024-02-20 20:24:34
...
一个对象, 默认是不可迭代的
let foo = {
foo1: 1,
foo2: 2
}
// 如果使用 of 或 展开运算符迭代 foo 会报错
for (const v of foo) {
console.log(v)
}
console.log([...foo])
那么, 如何使得 foo 变的可迭代呢?
最基本的不会报错的写法, 给 foo 这个对象添加一个 [Symbol.iterator] 的键, 其值为一个函数, 函数取啥名不重要, 重要的是它会返回一个具有 next 函数的对象
let foo = {
foo1: 1,
foo2: 2,
[Symbol.iterator]: () => {
return {
next() {
return { done: true }
// return { done: false, value: 'xxx' }
}
}
}
}
console.log([...foo])
这样就不会报错了, 但是打印出来的结果只是一个空数组
如果想打印 foo 的键值呢?
let foo = {
foo1: 1,
foo2: 2,
[Symbol.iterator]: function abandomName() {
let fooKey = Object.keys(foo)
return {
next() {
if (fooKey.length) {
return { done: false, value: fooKey.pop() }
}
return { done: true }
}
}
}
}
console.log([...foo])
你还可以将 [Symbol.iterator] 对应的函数抽出来
let fooKey = ['foo1', 'foo2']
let iterator = {
next() {
if (fooKey.length) {
return { done: false, value: fooKey.pop() }
}
return { done: true }
}
}
let foo = {
[Symbol.iterator]() {
return iterator
}
}
console.log([...foo])
可以看到, next 用于定制迭代的行为, 如果我想打印 1 ~ 9
let a = 0
const iterator = {
next() {
a++
if (a > 9) {
return { done: true }
}
return { done: false, value: a }
}
}
const oneToNine = {
[Symbol.iterator]: () => {
return iterator
}
}
console.log([...oneToNine])
我将 iterator 单独抽出来的写法
let a = 0
const iterator = {
next() {
a++
if (a > 9) {
return { done: true }
}
return { done: false, value: a }
}
}
let iteratorRes = iterator.next()
while(!iteratorRes.done) {
console.log(iteratorRes.value)
iteratorRes = iterator.next()
}
上一篇: 3、vim常用的命令
下一篇: Collection之Iterator