Understanding js closures and js closures

Source: Internet
Author: User

Understanding js closures and js closures
Closure is a difficult and characteristic of Javascript language. Many advanced applications rely on closures for implementation. 1. To understand the scope of variables, you must first understand the special scope of variables in Javascript. Variables have two scopes: global variables and local variables. The special feature of Javascript is that the function can directly read global variables.

1 var n=999;2   function f1(){3     alert(n);4   }5   f1(); // 999
On the other hand, local variables in the function cannot be read outside the function.
1 function f1(){2     var n=999;3   }4   alert(n); // error
Note that you must use the var command when declaring variables in a function. If you don't need it, you actually declare a global variable!
1 function f1(){2     n=999;3   }4   f1();5   alert(n); // 999
Second, how do I read local variables from the outside? For various reasons, we sometimes need to get local variables in the function. However, as we have already said, under normal circumstances, this cannot be done. It can only be implemented through a work und. That is to define another function within the function.
1 function f1(){2     n=999;3     function f2(){4       alert(n); // 9995     }6   }
In the code above, function f2 is included in function f1. All local variables in function f1 are visible to f2. But in turn, the local variables in f2 are invisible to f1. This is the unique "chain scope" structure (chain scope) of Javascript language. The sub-object will first look up the variables of all parent objects. Therefore, all variables of the parent object are visible to the child object, and vice versa. Since f2 can read local variables in f1, As long as f2 is taken as the return value, we can't read its internal variables outside f1!
function f1(){    n=999;    function f2(){      alert(n);    }    return f2;  }  var result=f1();  result(); // 999
Functions --------------------------------------------------- 3. The f2 function in the previous code is the closure. Closure definitions in various professional documents are very abstract and hard to understand. In my understanding, closures are functions that can read internal variables of other functions. In Javascript, only the subfunctions in a function can read local variables. Therefore, you can simply understand the closure as a function defined in a function ". Therefore, in essence, closure is a bridge connecting the internal and external functions of a function. Closure -------------------------------------------------- 4. The closure can be used in many places. It has two major functions: one is to read the internal variables of the function mentioned above, and the other is to keep the values of these variables in the memory. How can we understand this sentence? See the following code.
function f1(){    var n=999;    nAdd=function(){n+=1}    function f2(){      alert(n);    }    return f2;  }  var result=f1();  result(); // 999  nAdd();  result(); // 1000
In this Code, the result is actually the f2 function of the closure. It runs twice in total. The first value is 999, and the second value is 1000. This proves that the local variable n in function f1 has been stored in the memory and is not automatically cleared after f1 is called. Why? The reason is that f1 is the parent function of f2, and f2 is assigned a global variable, which causes f2 to always be in the memory, while f2 depends on f1, therefore, f1 is always in the memory and will not be recycled by the garbage collection mechanism after the call is completed. Another noteworthy part of this Code is the line "nAdd = function () {n + = 1}". The var keyword is not used before nAdd, therefore, nAdd is a global variable rather than a local variable. Secondly, the value of nAdd is an anonymous function, and this anonymous function itself is also a closure, so nAdd is equivalent to a setter, you can operate the local variables inside the function outside the function. Attention ------------------------------------------------ 5. Note 1 when using closures, the closure will save the variables in the function in the memory, causing high memory consumption. Therefore, the closure cannot be abused, otherwise, it may cause webpage performance problems and may cause memory leakage in IE. The solution is to delete all unused local variables before exiting the function. 2) The closure changes the value of the internal variable of the parent function outside the parent function. Therefore, if you use the parent function as an object, use the closure as its Public Method, and use internal variables as its private value ), be sure not to change the value of the internal variable of the parent function. Summary -------------------------------------------------- 6. If you can understand the running results of the following code, you should understand the operating mechanism of the closure.
var name = "The Window";     var object = {       name : "My Object",       getNameFunc : function(){         return function(){           return this.name;        };       }   };   alert(object.getNameFunc()());  //The Window
Example of JavaScript Closure
function outerFun(){  var a=0;  function innerFun()  {   a++;   alert(a);  }   }innerFun()
The above code is wrong. innerFun () is in the scope of outerFun (). It is wrong to call outerFun () externally. It is changed to the following, that is, the closure:
function outerFun(){  var a=0;  function innerFun()  {   a++;   alert(a);  }   }innerFun()
What is a closure: when an internal function is referenced outside the scope of its scope, it creates a closure for the internal function. If the internal function references a variable in the external function, after an external function is called, these variables will not be released in the memory because the closure needs them. ---------------------------------------------------------- let's take a look at an example.
function outerFun(){var a =0;alert(a);  }var a=4;outerFun();alert(a);
The result is. Because the var keyword is used inside the function to maintain the scope of a in outFun (). Then, let's look at the following code:
Function outerFun () {// No vara = 0; alert (a);} var a = 4; outerFun (); alert ();
The result is 0, 0. Why? The scope chain is the term used to describe a path. The variable value can be determined along this path. when a = 0 is executed, because the var keyword is not used, the value assignment operation will link to var a = 4 along the scope and change its value. ------------------------------------------------- if you are not very familiar with the javascript closure, then please refer to the reprinted Article below :( reprint: http://www.felixwoo.com/archives/247) a, what is the closure? The official explanation is: a closure is an expression (usually a function) that has many variables and is bound to these variables. Therefore, these variables are part of the expression. I believe that few people can directly understand this sentence, because he described it too academic. In fact, all functions in JavaScript are closures. But in general, nested functions produce more powerful closures, which are also called "closures" in most cases ". See the following code:
function a() {var i = 0;function b() { alert(++i); }return b;}var c = a();c();
This code has two features: 1. function B is nested inside function a; 2. function a Returns function B. So after var c = a () is executed, variable c actually points to function B and then executes c () then a window will pop up showing the I value (the first time is 1 ). This Code actually creates a closure. Why? Because variable c outside function a references function B in function a, that is, when function B inside function a is referenced by a variable outside function, A closure is created. Let's be more thorough. The so-called "closure" refers to defining another function in the constructor as the method function of the target object, and the method function of this object references temporary variables in the outer function body in turn. This allows the target object to indirectly retain the temporary variable value used by the original constructor as long as it can maintain its method throughout the lifetime. Although the call to the initial constructor has ended, the name of the Temporary Variable disappears, but the value of the variable can always be referenced in the method of the target object, this value can only be accessed in this way. Even if the same constructor is called again, only new objects and methods are generated. The new temporary variables only correspond to new values, which are independent of those called last time. Ii. What is the function of closure? In short, the function of the closure is that after a executes and returns, the closure makes the garbage collection mechanism of Javascript GC not to reclaim the resources occupied by, because the execution of the internal function B of a depends on the variables in. This is a straightforward description of the function of the closure, which is neither professional nor rigorous, but probably means that the process of understanding the closure needs to be gradual. In the above example, because of the existence of the closure, the I in a always exists after function a returns, so that each execution of c (), I is the value of alert after auto-increment 1. Then let's imagine another situation. If a does not return function B, the situation is completely different. Because after a is executed, B is not returned to the external world of a, but is referenced by a. At this time, a will only be referenced by B, therefore, functions a and B are referenced by each other without being disturbed by the outside world (referenced by the outside world), and functions a and B are recycled by GC. (The garbage collection mechanism of Javascript will be described in detail later.) 3. For a more in-depth understanding of the micro-world in a closure and the relationship between function a and nested function B, we need to introduce several other concepts: the excution context, the call object, the scope, and the scope chain ). The process from definition to execution of function a is used as an example to describe these concepts. When defining function a, the js interpreter sets the scope chain of function a to the "Environment" where a is located when defining function a. If function a is a global function, the scope chain contains only window objects. When function a is executed, a enters the corresponding execution environment (excution context ). In the process of creating the execution environment, a scope attribute is first added for a, that is, the scope of a, and its value is the scope chain in step 1. That is, the scope chain of a. scope =. Then, the execution environment creates a call object ). An activity object is also an object with attributes, but it does not have a prototype and cannot be directly accessed through JavaScript code. After creating the activity object, add the activity object to the top of the scope chain of. In this case, the scope chain of a contains two objects: The activity object of a and the window object. The next step is to add an arguments attribute to the activity object, which stores the parameters passed when calling function. Finally, all the form parameters of function a and the reference of internal function B are added to the activity object of function. In this step, the definition of function B is completed. As in step 1, the scope chain of function B is set to the environment defined by B, that is, the scope of function. At this point, the steps from definition to execution of function a are completed. At this time, a returns the reference of function B to function c, and the scope chain of function B contains the reference to the activity object of function, that is to say, B can access all variables and functions defined in. Function B is referenced by Function c, and function B is dependent on function a. Therefore, function a is not recycled by GC after return. When function B is executed, it will be the same as the above steps. Therefore, during execution, B's scope chain contains three objects: B's activity object, a's activity object, and window object, as shown in :, when accessing a variable in function B, the search order is: first search for its own activity object. If it exists, return. If it does not exist, continue searching for the activity object of function, search until it is found. If function B has a prototype object, search for its own prototype object after searching for its own activity object. This is the Variable Search Mechanism in Javascript. If the entire scope chain cannot be found, undefined is returned. This section describes two important words: function definition and execution. The scope of the function is determined when the function is defined, rather than when the function is executed (see steps 1 and 3 ). Use a piece of code to illustrate this problem:
function f(x) {  var g = function () { return x; }  return g;}var h = f(1);alert(h());
In this Code, the variable h points to the anonymous function in f (returned by g ). Assume that the scope of function h is determined by the execution of alert (h (), then the scope chain of h is: h activity object-> alert activity object-> window object. Assume that the scope of function h is determined during definition, that is, the anonymous function pointed to by h has already determined the scope. In execution, h's The scope chain is: h activity object-> f activity object-> window object.If the first hypothesis is true, the output value is undefined. If the second hypothesis is true, the output value is 1. The running result proves that the 2nd assumptions are correct, indicating that the function scope is indeed determined when the function is defined. Iv. Closure application scenarios protect variable security in functions. Taking the initial example as an example, in function a, I can only access function B, but cannot access function B through other channels, thus protecting the security of function I. .Maintain a variable in the memory. Still, for example, because of the closure, the I in function a is always in the memory, so each execution of c () will add 1 to the I self. By protecting the security of variables, JavaScript private attributes and private methods (cannot be accessed externally) Private attributes and methods cannot be accessed outside of Constructor.
function Constructor(...) {    var that = this;    var membername = value;  function membername(...) {...}}
The above three points are the most basic application scenarios of closures. Many classic cases are based on this. 5. The garbage collection mechanism of Javascript is in Javascript. If an object is no longer referenced, it will be recycled by GC. If two objects are referenced by each other and are no longer referenced by 3rd The two referenced objects will also be recycled. Because function a is referenced by function B and function B is referenced by Function c outside of function a, this is why function a is not recycled after execution.6. Conclusion: Understanding the closure of JavaScript is the only way to move towards a senior JavaScript programmer. Only by understanding its interpretation and operating mechanism can we write safer and more elegant code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.