Check out a free preview of the full The Hard Parts of Asynchronous JavaScript course
The "Iterator Function" Lesson is part of the full, The Hard Parts of Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Will examines the building blocks of iterators and their ability to turn data into "streams" of actual values that can be accessed one after another.
Transcript from the "Iterator Function" Lesson
[00:00:00]
>> Will Sentance: Here we go. When the function inner is defined it gets a bond to surrounding local memory. You got that bit in which it's being defined. We return out the function known as inner. The surrounding live data is returned too attach the back of the function definition itself, which we then give a new global label, returnNextElement.
[00:00:16]
When we call returnNextElement and don't find array or i and it's local immediate execution context, we look into the function definition's backpack of live data. The backpack has some official names. Okay, let's first say, how is this bond to the backpack actually stored on the function? It's stored in a hidden property, we can actually see it in the Chrome dev tools.
[00:00:38]
We can't access it meaningfully, [[scope]]. If you were to console.log return next element, press a little down arrow, you'd see [[scopes]]. And that will have stored in it, so it's on this hidden property scope, and that would have stored in it all this data, okay? So with that in mind, by the way, in general, a language who's rules, or it's rule about what data is available to you is about where the function is born, where it was defined, is known as a lexically-scoped language.
[00:01:24]
That means a language that says, where you defined me is what determines, the positioning of my definition inside another function, is what determines what data I have available to me when I'm eventually run, eventually called. Wherever you end up calling me. Because I attached the data from around me when I was born, to me.
[00:01:42]
That's the first place I look, besides the function execution context itself. That is known as a lexically scoped language, as opposed to a dynamically. It's called a statically scoped language, lexically or statically. Statically or lexically-scoped language. You could very easily imagine a language where the next place I'd look is global.
[00:02:00]
Not JavaScript. Is a statically or lexically-scoped language. So we can call this backpack of data, wanna be really fancy? We can call it a persistent lexical scope. This is our lexical scope bond, or reference, persistent lexical scope reference data. Very catchy. Persistent lexical scope reference data. It's very literal.
[00:02:30]
Go and say that in your senior year engineering interviews, they'll be very happy with you.
>> [LAUGH]
>> Will Sentance: You may also remember that the memory is called the variable environment. That means that the variables is available to you around. So you can call it also the variable environment has been enclosed, closed over.
[00:02:48]
And returned out of the function. So, you might call it the Closed Over Variable Environment, the COVE.
>> Will Sentance: Also not catchy. People intuitively call it the backpack. People also unfortunately I think unintuitively but colloquially typically call it, that's the best name. Typically call it the closure. You'll hear engineers say put those values in the closure.
[00:03:19]
Why I don't love that name is because firstly, it doesn't make sense. But secondly, we call the whole concept closure, the idea of functions persisting their lexical scope references, their surrounding data when they were born. We call the whole concept closure, and we call the backpack the closure.
[00:03:36]
So I think that's just a bit too much under one label. And certainly a label doesn't mean that much to me anyway. So I like the name backpack but people tend to call this backpack of data the closure. It is to say that our functions get to have memories.
[00:03:52]
Not their local memory that gets deleted each time but a persistent cache of data attached to their very down definition. Meaning we can have a function that when called, doesn't find data inside itself and looks in its persistent cache attached to it. All bundled up on a single function.
[00:04:08]
It's a pretty beautiful design. All right, returnNextElement, that function has everything we need, by the way, the only way you can get a backpack in a meaningful way is to return the function from where it was born. Is to return the function and bring with it the data, that's how you get that persistent data.
[00:04:28]
So returnNextElement has everything we need all bundled up in it. It has the underlying array in the backpack, it has the position we're currently in, in our flow of elements coming out to us in the backpack. And the ability when it's run when the function actually itself has run to return out that next element.
[00:04:49]
This relies completely on the special property of functions in Java that also were born inside other functions and returned, they get a backpack of persistent data that they have access to when they're called. What is the posh name for returnNextElement? Who knows the posh name for returnNextElement?
>> Will Sentance: It's known as an iterator.
[00:05:09]
Any function that when called gives me out the next element from my flow of data. My collection of data gives me the next element. And when I run it I switch on the flow and get the returning next element, I run the function again, I switch on the flow, get the fnext element.
[00:05:24]
That is known as an iterator function. It gives me one by one, every time it's called my next element from my underlying collection. I refer the name returnNextElement, we call these iterators. All right, so iterators I'm gonna go to pairing in a second and then we're gonna come back to discover.
[00:05:40]
Here, what our flow of data is, is preset. We can't go back and change it. It was sort of preset from at moment we created the returnNextElement function, which was born inside create function. We can't go back and change it. I mean we could design returnNextElement in some way to be able to mutate it.
[00:06:00]
But, basically we can't go back and change it. We're gonna discover in our next session, there's now a new way of dynamically controlling the values that come out of that flow, known as generator functions. But first, iterators turn our data, our collections of numbers, or list, or whatever, into streams, into flows of actual values that we can access one after another.
[00:06:23]
No longer are we getting a static list of elements and we go grab element at zero, go grab element at one. Now we run a function and it gives us the next element, one by one by one. Now we have functions that hold our underlying array, the position we're currently in, and return out the next item in the streams of elements from our array when it's run.
[00:06:45]
This [INAUDIBLE] has our for loops, known as for of loops, that show us the element itself in the body of a loop. No accessing some from some array the position, and you'll see these in the challenges, but rather instead actually give us out into the body of our for loop the actual element.
[00:07:01]
Cuz behind the scenes it's running returnNextElement. And returning that individual element and giving it the label, I don't know, whatever you want, element, next element, whatever you want to call it. And more deeply it allows us to rethink our collections, our static lists of data, our arrays as flows of elements cuz most of the time we store a list of data, we don't really care about it so much as a static thing.
[00:07:25]
We want to be able to get the elements one by one. That's actually what we want to do with it most of the time. We're not just sort of just leaving it there, we want to get the elements out one by one. And maybe conflate them, join them together, do something with them.
[00:07:38]
It allows us to rethink arrays as flows of elements themselves. Which we can interact with by calling a function that switches that flow on to give us out our next element. We have truly separated, decoupled, the process of accessing each of our elements, from what we end up wanting to do to our individual elements.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops