Useful information sharing: Let you learn JS closures in minutes

Useful information sharing: Let you learn JS closures in minutes

1. Closure, a sneak peek

When I come into contact with a new technology, the first thing I will do is to find its demo. For us, reading code can help us understand the essence of a thing better than natural language. In fact, closures are everywhere, for example, the core code of jQuery and Zepto is contained in a large closure, so I will write the simplest and most primitive closure below to help you create a picture of closure in your mind:

  1. function A(){
  2. function B(){
  3. console.log( "Hello Closure!" );
  4. }
  5. return B;
  6. }
  7. var C = A();
  8. C(); //Hello Closure!  

This is the simplest closure.

After having a preliminary understanding, let's briefly analyze how it is different from ordinary functions. The above code is translated into natural language as follows:

(1) Define a general function A

(2) Define a normal function B in A

(3) Return to B in A

(4) Execute A and assign the result of A to variable C

(5) Execute C

To summarize these 5 steps in one sentence:

Function B inside function A is referenced by a variable c outside function A.

If we further process this sentence, it becomes the definition of closure:

When an inner function is referenced by variables outside its outer function, a closure is formed.

So, when you perform the above 5 steps, you have defined a closure!

This is closure.

2. The purpose of closure

Before understanding the role of closures, let's first understand the GC mechanism in Javascript:

In Javascript, if an object is no longer referenced, it will be reclaimed by GC, otherwise the object will always be kept in memory.

In the above example, B is defined in A, so B depends on A, and the external variable C references B, so A is indirectly referenced by C.

That is to say, A will not be reclaimed by GC and will always be kept in memory. To prove our reasoning, the above example is slightly improved:

  1. function A(){
  2. var count = 0;
  3. function B(){
  4. count++;
  5. console.log(count);
  6. }
  7. return B;
  8. }
  9. var C = A();
  10. C(); // 1  
  11. C(); // 2  
  12. C(); // 3  

count is a variable in function A, and its value is changed in function B. Each time function B is executed, the value of count is increased by 1. Therefore, the count variable in function A will always be stored in memory.

When we need to define some variables in a module and hope that these variables are always kept in memory but do not "pollute" global variables, we can use closures to define the module.

3. Advanced writing of closures

The above is actually the most primitive way of writing. In actual applications, closures and anonymous functions are often used together. The following is a common way of writing a closure:

  1. ( function (document) {
  2. var viewport;
  3. var obj = {
  4. init: function (id) {
  5. viewport = document.querySelector( "#" +id);
  6. },
  7. addChild: function (child){
  8. viewport.appendChild(child);
  9. },
  10. removeChild: function (child){
  11. viewport.removeChild(child);
  12. }
  13. }
  14. window.jView = obj;
  15. })(document);

The function of this component is to initialize a container, then add subcontainers to this container, and remove a container.

The function is very simple, but there is another concept involved here: immediately executing a function. Just briefly understand it, and the key point to understand is how this writing method implements the closure function.

The above code can be split into two parts: (function(){}) and (). The first () is an expression, and this expression itself is an anonymous function, so adding () after this expression means executing this anonymous function.

Therefore, the execution process of this code can be decomposed as follows:

  1. var f = function (document) {
  2. var viewport;
  3. var obj = {
  4. init: function (id) {
  5. viewport = document.querySelector( "#" +id);
  6. },
  7. addChild: function (child){
  8. viewport.appendChild(child);
  9. },
  10. removeChild: function (child){
  11. viewport.removeChild(child);
  12. }
  13. }
  14. window.jView = obj;
  15. };
  16. f(document);

In this code, we seem to see the shadow of closure, but there is no return value in f, which seems to be inconsistent with the conditions of closure. Pay attention to this code:

  1. window.jView = obj;

obj is an object defined in function f, which defines a series of methods. Executing window.jView = obj means defining a variable jView in the window global object and pointing this variable to the obj object, that is, the global variable jView references obj. The function in the obj object references the variable viewport in function f, so the viewport in function f will not be recycled by GC and will be kept in memory. Therefore, this writing method meets the closure conditions.

4. Summary

This is the simplest understanding of closures. Of course, there is a deeper understanding of closures, which involves more. You need to understand the execution context, activation object, scope, and the operation mechanism of the scope chain. But as a beginner, you don't need to understand these for the time being. After you have a simple understanding, you must use it in actual projects. When you use it more, you will naturally have a deeper understanding of closures!

<<:  GPU temperature is too high during deep learning training? Enter these few lines of commands to quickly cool it down

>>:  MVVM mode of mobile development architecture

Recommend

How much does it cost to create a fruit mini program in Qingyang?

How much does it cost to produce the Qingyang Fru...

New marketing method for increasing followers on Xiaohongshu

If you often browse Xiaohongshu, do you have this...