🌧 question
As we know, type Array has iterator but object doesn't.
const [a, b] = [1, 2] // this is gonna work
const [a_, b_] = {
a_: '1',
b_: '2'
} // end up with a typeError: 'object is not iterable'
Take this into consideration, how to make objects iterable?
⭐ generator
Once I saw a description in introduction about Generator function.
function* gen(){}
const g = gen()
g === g[Symbol.iterator]()
So, if we wanna make a object iterable, generator is gonna to be a good choice.
const obj = {
a_: 1,
b_: 2,
[Symbol.iterator](){
let index = 0
let value_array = Object.values(this)
return {
next() {
if (index < value_array.length) {
return {
done: false,
value: value_array[index]
}
}
return { done: true, value: undefined }
}
}
}
}
const [a, b] = obj
console.log(a, b) // well this is valid
Till here we solve the problem
By the way, if a object can achieve
[Symbol.iterator]and it is able to be circulated byfor...of
🐸 what's more
Here is a simple implement of Generator function below.
function* gen() {
let x = 1
let y = yield x + 1
let z = yield y * 4
let s = yield z % 3
return x + y + z + s
}
const g = gen()
g.next()
// guess what will `g.next` return
If you guys have learned or met some situation like this, it is easy to understand that only the first
yieldwill return{ value: 2, done: false }and others will get a result either{ value: NaN, done: false }or{ value: undefined, done: true }
Ok, if you know why, you can just skip to the next chapter; and if you still wonder why, I will show you my opinions.
Well, just take yield as a temporary return and its priority is higher than = .When you get this, the code has changed
function* gen() {
let x = 1
yield x + 1
let y // undefined
yield y * 4 // NaN
let z // undefined
yield z % 3 // NaN
let s // undefined
return x + y + z + s // NaN
}
const g = gen()
g.next()
And also we have a solution for this problem -- just add a parameter in function next
g.next(2)
this gonna change the code running process
function* gen() {
let x = 1
yield x + 1
let y = 2 // 2 is come from `next`
yield y * 4
let z // undefined
yield z % 3 // NaN
let s // undefined
return x + y + z + s // NaN
}
const g = gen()
g.next()
What you should notice is that: by the parameter in
nextis representing which is lastyieldexpression returns, so the first time when you callnextthe parameter is invalid.