This article brings you knowledge about JavaScript generators, how generators are implemented, and the use of generator functions to customize iterators. I hope it will be helpful to you.
can be understood as a traverser of the internal state of a function. Every time the generator is called, the internal state of the function changes.
#function
and the function name*
yield
expressions can be used inside the function body to define different statesnext
method in the generator, which traverses the next stateyield
Expression: equivalent to the pause flag, only callingnext
method will traverse the next internal statenext
method, execution starts from the beginning of the function or where it last stopped until it encounters Until the nextyield
expression (orreturn
statement)yield
expression The formula is the pause sign)Let us understand it through an example:
(Take the familiar Hello World!!!)
function* sayHW(){ yield "Hello"; yield "World"; return "!!!";}let say = sayHW();console.log(say.next());console.log(say.next());console.log(say.next());
Thenext
method is called three times in total:
When called for the first time, it encountersyield
and stops,next
method Returns an object whosevalue
attribute is the value of the currentyield
expressionHello
, and the value of thedone
attribute isfalse
, indicating that the traversal has not ended
When calling for the second time, it stops when encounteringyield
, and thenext
method returns an object with itsvalue
The attribute is the value of the currentyield
expressionWorld
, and the value of thedone
attribute isfalse
, indicating that the traversal has not ended
Then until the third call, execution reaches thereturn
statement (if not, execution continues until the end of the function). At this time, the value of thevalue
attribute returned bynext
is the value after thereturn
statement, and the attribute ofdone
istrue
(If there is noreturn
,done
is stillfalse
at this time), indicating the end of the loop.
Next, we output againnext
:
console.log(say.next());
At this timenext
will return this object,value
isundefined
,done
is ·true
(regardless of whether there is areturn
statement before, the function has already been run at this time It’s done, sodone
are alltrue
)
As explained above , we can know that the generator function allows us to define afunctionthat contains its own iteration algorithm, and at the same time it can automatically maintain its own state.
Since custom iterators need to maintain their internal state explicitly, we can use it to customize iterators.
(If you don’t know about iterators, you can read this article first: JavaScript iterators)
Next, let us understand it through an example:
Now there is acolors
object, we want to usefor...of
to traverse it, then we can customize the iterator.
let colors = { blue : "蓝色", green : "绿色", yellow : "黄色"}
Normal writing:
colors[Symbol.iterator] = function() { let keys = Object.keys(colors); // 如果用 let keys = Reflect.ownKeys(colors),keys 就会包括一些不可枚举的属性 // 那么后面的 len 要减一,减去Symbol.iterator这个属性 // 根据实际情况选择使用 let len = keys.length; let index = 0; return { next : function() { if (indexWriting using generator function:
colors[Symbol.iterator] = function* () { let keys = Object.keys(colors); // 如果用 let keys = Reflect.ownKeys(colors),包括了一些不可枚举的属性 // 那么后面的 len 要减一,减去Symbol.iterator这个属性 // 根据实际情况选择使用 let len = keys.length; let index = 0; while(indexThat's it. After using the generator function to customize the iterator, it is much simpler.
[Related recommendations: javascript learning tutorial]
Copy after login
The above is the detailed content of Understand what a JavaScript generator is in ten minutes (organized and shared). For more information, please follow other related articles on the PHP Chinese website!