Part I. Environment
Let’s talk about the environment. Our planet is huge, but we all share it. If you build a chemical plant, it would be nice to isolate it from the outside world so that what happens in it remains inside. You can say that in this building its environment, microclimate, isolated from the external environment.
Your program has a similar structure for similar reasons. What you create outside — outside functions, if statements, loops, and other blocks of code — is in an external, global environment.
multiplier and variable
result- all in the external environment. These components have a "global scope". Scope means "area where components are available."
multiplier is a constant inside the function
x. Since it is inside a block of code, it is a local constant, not a global one. It is visible only inside this function, but not outside. It has a local scope.
multiplier has another component from the local scope - the argument
num. It is not defined as clearly as constants or variables, but behaves almost like a local variable.
We do not have access to the
x outside, as if it does not exist there:
console.log Called in the global environment, and
x not specified in this global environment. Therefore, we get Reference Error.
We can set
Now there is a global one
x and its value has been displayed, but the local one
x inside the function
multiplier is still visible only inside this function. These two
x have nothing to do with each other, they are in different environments. They do not collapse into one, despite the fact that they have the same name.
Any code block surrounded by curly brackets turns into a local environment. Here is an example with a block
The same works for cycles
Ok, local is not visible outside. But the global is visible everywhere. Even inside something? Yes!
This global variable
a has changed inside the function
changer. Function generally perform something only when it is called, not when it is determined, so that initially
0, but after the call
a it becomes
Although it is tempting to put everything in the global scope and forget about the complexities of separate environments — this is a terrible practice. Global variables make your code incredibly fragile. In that case, anything can break anything. Therefore, avoid global scope, keep things where they belong.
Part II. Lexical scope
Take a look at this program:
multiplierreturns the product
aset inside, but
Trying to solve the multiplication
b. He begins to search locally and goes outside, one area of view per step, until he finds what he needs or until he realizes that it is impossible to find.
ainside the local scope - inside the function
multiplier. He finds the value immediately and goes to
b. It is impossible to find a value
bin the local scope, so it goes to the outer area. Here he finds
b- this is 10.
a * bturns into
5 * 10, and then into
This whole piece of code could be inside another function, and still inside another function. And if it had
boutside the function, layer by layer.
a = 7did not affect the calculation,
awas found inside, so the external
adid not play a role.
This is called a lexical scope. The scope of any component is determined by the location of this component within the code. And nested blocks have access to their external scopes.
Part III. Closures
Most programming languages have something like a scope or environment, and this mechanism allows closures to exist. A closure is just a fancy name for a function that remembers the external things used inside.
Before we continue, let’s remember how functions are created and used:
f - a rather useless function, it always returns 0. The whole set consists of two parts: a constant and the function itself.
It is important to remember that these two components are separate. The first is a constant named
f. Its value could be a number or a string. But in this case, its value is a function.
We used the analogy in previous lessons: constants like sheets of paper — the name on one side, the value on the other. Consequently,
f- a sheet of paper with
fon one side and a description of the function being launched on the other.
When you call this function, like this:
… creating a new box based on the description on this sheet of paper.
Ok, back to the closures. Consider the following code:
createPrintercreates a constant
nameand then a function with the name
printName. Both are local to the function
createPrinter, and are available only inside
It itself has
printNameno local components, but it has access to the area of visibility, where it is located, to the external area, where the constant is given
The function then
createPrinterreturns the function
printName. Remember, function definitions are descriptions of running functions, just pieces of information, like numbers or strings. Therefore, we can return the definition of a function as we return a number.
In the outer scope, we create a constant
myPrinterand set its value, which is returned
createPrinter. It returns a function, so now
myPrinterit is a function. Call her, and the screen will display "King".
There is a strange thing here: this constant
namewas created inside the function
createPrinter. The function was called and executed. As we know, when a function finishes, it no longer exists. This magic box disappears with all its insides.
BUT he returned another function, and already she somehow remembered the constant
name. Therefore, when we called
myPrinter, it brought out "King" - the memorized value, despite the fact that the scope where it was set no longer exists.
The function that was returned from
createPrinteris called a closure. A closure is a combination of a function and the environment where it was specified. The function "closed" in itself some information from the scope.
- Variables and scoping / Exploring JS
- Scope / Wikipedia
- Closure / Wikipedia
- Closures in JS / MDN (here the examples use ES5, the previous version of the language standard)