1. Weird Closure
Javascript has a special feature-closure,. NET programmers are familiar with Object-Oriented Programming (OOP), while closures from Functional Languages seem strange. Many programmers are far away from it.
For closures, we should start with the features of functional languages.
I wonder if you have found that there are no keywords such as public and private in javascript, and there is no class. Although there are objects, however, the object is far from being a first-class citizen in C #. In js, you can write programs without objects. It is just a form of data representation, but it can or cannot be used.
2. How does closure come from?
How can we implement data protection in javascript? Closure is a powerful tool for implementing it. We need to put down common objects and understand how javascript works.
In javascript, you can define a new function in the function. This nested function can also be used as the return value of the function and referenced by external variables. In a common programming language, for example, C, although the function pointer concept exists, the so-called function pointer is only the address of a piece of code, and the function reference returned by javascript, this is not limited.
In C language, when a function is running, partial variables are stored in the stack. After the function is executed, the system will pop up the stack.
In fact, in javascript, every time a function is executed, note that the system will create an environment object for the function to run at the same time, the local variables during this operation are associated with this environment object. In normal functions that do not return functions, after the function is executed, the Environment objects are released together. If a function returns a nested function defined in an external function, the environment object will not be released. That is to say, a visible function object is returned at this time, an invisible Dark Matter-environment object of the external function is attached.
A visible function object plus an implicit environment object is a closure.
This environment object can only be accessed implicitly through this function. We do not reference it, nor can we directly access it. The result is information hiding.
3. Implement private data
Consider the following code
- function outer() {
- var name = "Alice";
- var inner = function () {
- return name;
- }
- return inner;
- }
-
- var fn = outer();
- alert(fn());
In this example, the simple fn function actually hides the environment object created during the execution of the outer function. Therefore, you can get the name of Alice Through fn, there are no other channels for this name.
4. Why is data messy?
Let's look at another classic example.
- <body>
- <div>
- <a href="#">Click Me!</a>
- <a href="#">Click Me!</a>
- <a href="#">Click Me!</a>
- </div>
- <script type ="text/javascript">
- function main(links) {
- for (var i = 0; i < links.length; i++) {
- links[i].onclick = function () {
- alert(i + 1);
- }
- }
- };
- main(document.getElementsByTagName("a"));
- </script>
-
- </body>
What is the pop-up? It seems that there are three cycles. 1, 2, and 3 should be displayed. Run it and you will see that it is actually 4, 4, 4!
Isn't it weird?
From the perspective of closures, it is very simple. How many times has the main function been executed? Only once, a closure object is created during execution, which references the partial variable I defined in main. in the loop body, three internal functions are actually created, they reference the same environment object. These functions are registered on the onclick event of the link. In fact, the main function has been passed out. Therefore, the main environment object has quietly become a dark matter, after the loop is completed, I is finally assigned the value 3. The three functions access the I in the same environment object. Therefore, when you click the link, the result of 4 is normal.
5. You need to contact the person who calls the bell.
What should I do if I want to get the result of 1, 2, and 3?
We can define an internal function so that it can be executed three times. This will create three corresponding environment objects. We can make these three environment objects contain different values.
- function main(links) {
- var inner = function (elem, i) {
- elem.onclick = function () {
- alert(i + 1);
- };
- };
- for (var i = 0; i < links.length; i++) {
- var elem = links[i];
- inner(elem, i);
- }
- };
Since the inner function is executed three times, three different environment objects will be created, and I in each environment object is different. In this way, functions registered to onclick can access different values.
Closure concept
Here, we can look at the concept of closure. This is the case from Wikipedia.
In computer science, Closure is short for Lexical Closure. It refers to a function that references free variables. This referenced free variable will exist with this function, even if it has left the environment where it was created. Therefore, there is another saying that a closure is an entity composed of a function and its reference environment.