This article introduces how to use JavaScript closures. For more information, see.
A closure is a way to access and manipulate external variables in a function. In general, we define some variables outside the function for internal use.
The Code is as follows: |
Copy code |
Var a = 1; Function fn (arg ){ Var B = 2; Function fnInner (arg ){ Console. log (a); // access global variables Console. log (B); // access the variables in the external function. Console. log (arg); // access the function's own Variables } FnInner (3 ); } |
The closure of the fn function references variable B, and the function itself. The fnInner function references the parameters passed to B,. Note that although the function does not create a variable to save the data to be referenced, saving and referencing these variables will consume memory.
Private variable
The JavaScript language does not provide a way to create private variables, but we know that variables outside the function cannot access the variables inside the function, which means we can create private variables like this:
The Code is as follows: |
Copy code |
Function (){ This. public = 1; // public can be accessed outside the Function Var private = 1; // The private variable cannot be accessed outside the function. } |
Callback functions and timers
Sometimes we write a callback function like this.
The Code is as follows: |
Copy code |
Var a = 1; JQuery. ajax ({ Url: "test.html ", Success: function (html ){ Console. log (); } }) |
Similarly, when we set the timer, we inserted a function into the queue after MS and waited for execution.
The Code is as follows: |
Copy code |
Var a = 1; SetTimeout (function (){ Console. log (); },1000 ); A = a + 1; |
The results in the ajax callback may be easier to guess. The anonymous function itself is a closure and stores the value of variable a for access. The second timer callback mainly needs to be noted that the value referenced by the closure is generated during the execution period. Although we have defined an anonymous function before a = a + 1, however, when the anonymous function is inserted to the end of the execution queue, a = a + 1 is executed first, and then the anonymous function is executed, that is, the value returned in this example is 2.
Change the context of the Closure
There is such a piece of code
The Code is as follows: |
Copy code |
Var Button = { Click: function (){ Console. log (this ); This. clicked = true; } }; Var elem = document. querySelector ("body "); Elem. addEventListener ("click", Button. click, false ); |
Our goal is to change the clicked value of the Button object by clicking the body, but it fails.
Although we tried to point this to the Button During the definition, after addEventListener, this was directed to elem again.
There are many solutions.
In a browser that supports Function. prototype. bind, you only need to modify the code.
The Code is as follows: |
Copy code |
Var Button = { Click: function (){ Console. log (this ); This. clicked = true; } }; Var elem = document. querySelector ("body "); Elem. addEventListener ("click", Button. click. bind (Button), false ); |
NOTE: For the Function. prototype. bind method, see the description in ECMAScript 262 15.3.4.5. The Function is similar to apply, but the original Function is not executed.
If Function. prototype. bind is not supported, we can implement a bind Function by ourselves.
The Code is as follows: |
Copy code |
Function bind (context, name ){ Return function (){ Return context [name]. apply (context, arguments ); }; } Var Button = { Click: function (){ Console. log (this ); This. clicked = true; } }; Var elem = document. querySelector ("body "); Elem. addEventListener ("click", bind (Button, "click"), false ); |
See secrets of the JavaScript ninjia from John Resign.