Closures are a way to access and manipulate external variables within a function, and in general we define variables outside the function for use within functions.
The code is as follows |
Copy Code |
var a = 1; function fn (ARG) { var B = 2; function Fninner (ARG) { Console.log (a); To access global variables Console.log (b); Accessing variables in external function bodies Console.log (ARG); Accessing variables of the function itself } Fninner (3); } |
The closure of the FN function refers to the variable B, as well as the function itself. The Fninner function refers to the b,a, passed to its arguments. We need to be aware that while the function does not specifically create a variable to hold the data to be referenced, saving and referencing these variables can still lead to memory consumption.
Private variable
The JavaScript language itself does not provide a way to create a private variable, but we know that a variable outside of a function cannot access a variable within a function, which means we can create a private variable like this:
The code is as follows |
Copy Code |
function () { This.public = 1; Public can be accessed outside the function var private = 1;//private variable cannot be accessed outside of 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 (a); } }) |
Similarly, when setting the timer, we insert a function into the queue after 1000ms to wait for execution
The code is as follows |
Copy Code |
var a = 1; settimeout (function () { Console.log (a); },1000); A = a + 1; |
The results in an AJAX callback might be easier to guess, and the anonymous function itself is a closure that holds the value of variable a so that it can be accessed. and the second timer callback is basically to say, the value that the closure refers to is generated during the execution period, and while we define the anonymous function before a = a+1, but the execution occurs because the anonymous function is inserted at the end of the execution queue, a = a +1 executes first, then the anonymous function is executed. In other words, this example returns a value of 2.
Change the context of a closure
There's this 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 aim is to change the clicked value of the button object by clicking the body, but it fails
Although we tried to make this point to the button when we were defining it, after AddEventListener, this was also pointed to Elem.
There are many ways to solve this problem.
In browsers that support Function.prototype.bind methods, we simply need to modify the code to
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: The Function.prototype.bind method refers to the description in ECMAScript 262 15.3.4.5, and is similar to apply, but does not perform the original function
If Function.prototype.bind is not supported, then we can implement a bind function 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); |
This article refers to the "Secrets of the JavaScript Ninjia" from John resign