What is closure:
is a scope created by a function when it is created to allow its own function to access and manipulate variables other than that of its own function
Closures enable functions to access all variables and functions of the scope when the function is declared
The example in the book I see is inexplicable .... Even take it for granted that ....
Let's just write it.
var outvalue= ' ninja ';
var later;
function Outfunction () {
var innervalue= ' Samurai '
function innerfunction (paramvalue) {
Console.log ( Outvalue)//global scope of certainty can get
console.log (innervalue)//Because the closure of the formation of the innerfunction function is always exist will protect the scope will not be garbage collection
Console.log (paramvalue)//Incoming parameter is also able to
Console.log (toolate)//In the calling method is Toolate has been declared
}
later= innerfunction;//this forms a closure.
}
Console.log (toolate)
var toolate= ' Hello '
outfunction ();
Later (' Wakizashi ')
using closures
At least on the top we know, the use of closures, now see what the specific purpose of using closures to simulate private variables
function Ninja () {
var feinit=0;
This.getfrinit=function () {return
feinit;
}
This.feinits=function () {
feinit++;
}
}
var ninja=new ninja ();
Ninja.feinits ();
Console.log (Ninja.getfrinit ())//1
In fact, this usage, in ES6 already has an alternative, where ninja in the Feinit variable if you do not pass the method you are unable to modify its callback and timer
Basically it's not to mention that most anonymous functions appear in callbacks .... Binding Function Context
Let's take a look at an example:
var button={
Clicked:false,
click:function () {
this.clicked=true;
Console.log (button.clicked);
}
var Elem=document.getelementbyid ("Test");
Elem.addeventlistener ("click", Button.click,false);
Would you know if the clicked in the button would be true and he would be false?
Why is that?
Because in the example, the event handling system of the browser thinks that the context of the function call is the target element of the event
Which is the DOM element, not the button function.
So the assignment didn't work.
Continue to modify this example you're not mistaken or apply
function bind (context, name) {return
function () {return
context[name].apply (context,arguments);
}
}
var button={
clicked:false,
click:function () {
this.clicked=true;
Console.log (button.clicked);
}
var Elem=document.getelementbyid ("Test");
Elem.addeventlistener ("Click", Bind (Button, "click"), False);
And here the closure is passed to the button function overload with the parameters of bind
Cache Memory:
There are two ways to implement it, the first to modify an existing function, or to create a new function that is updated based on an existing function. To modify an existing function to add a property memory field
Function.prototype.memoized=function (key) {
this._value=this._value| | {};
Return this._value[key]!==undefined?
This._value[key]:
this._value[key]=this.apply (this,arguments);
function IsPrime (num) {
var prime=num!=1;
for (Var i=2;i<num;i++) {
if (num%i==0) {
prime=false;
break;
}
}
return prime;
}
Console.log (isprime.memoized (5))
Console.log (isprime._value[5))
In fact, this is the same as the self-memory function I wrote before, and if you don't know how to write this, look at the previous
JavaScript Ninja cheats Fourth Chapter notes (function Advanced) The second use closure implementation
Function.prototype.memoized=function (key) {
this._value=this._value| | {};
Return this._value[key]!==undefined?
This._value[key]:
this._value[key]=this.apply (this,arguments);
Function.prototype.memoize=function (key) {
var fn=this;
return function () {return
fn.memoized.apply (fn,arguments);
}
}
var isprime= (function (num) {
var prime=num!=1;
for (Var i=2;i<num;i++) {
if (num%i==0) {
prime=false;
Break;}}}
). Memoize ();
Console.log (IsPrime (5))
You can see the omission of a step, you can see the code call IsPrime (), it is called memoize, followed by the value of the closure of the logic
But it's a little bit complicated to write, the back optimization function Encapsulation
Function wrapping is a technique for encapsulating function logic to overload the creation of new or inherited functions within a single step. The most valuable scenario is when you overload some existing functions while maintaining that the original function can still be used effectively after being packaged.
function Wrap (object,method,wrapper) {
var fn = Object[method];
return Object[method] = function () {return
wrapper.apply, This,[fn.bind (This)].concat (
Array.prototype.slice.call (arguments)));}
if (Prototype.Browser.Opera) {
wrap (element.methods, "Readattribute", function (original,elem,attr) {
return attr = = "title"? Elem.title:original (elem,attr);}
The above code first saves the original method in the variable FN, and later we will access it via the closure of the anonymous function. We then use a new anonymous function to overload the method. The new function executes the wrapper function wrapper that was passed in before and passes a reconstructed argument list. When we build this argument list, we want the first argument to be the original function we want to overload, so we create an array that contains a reference to the original function and appends the original parameter to the array. Instant function (immediate function)
(function () {}) ();
We use it often when we're writing frames, so let's dissect this code.
The first bracket (...) is ignored. ();
We know that () more is used to call the function, the first () is what to do, is used to delimit the scope of the expression
such as (3+4) *5 this () is to delimit the expression orientation
And in the first bracket, you can write a function, or an anonymous function like
(function () {}) ();
And the back bracket executes the function, and the inside is destroyed.
Let's take a look at the temporary scope and private variables of the immediate function:
(function () {
var numclick=0;
Document.addeventlistener ("click", Function () {
alert (++numclick);
},false)
}) ()
You can see that the Numclick property only has access to the property in the closure, while the function runs the click event to be bound and externally inaccessible
This is also one of the most common forms of instant function usage: simple, self-wrapping solves the problem of cyclic variables
<body>
<div style= "width:500px;height:500px;background-color:red" ></div>
<div Style = "Width:500px;height:500px;background-color:green" ></div>
<div style= "width:500px;height:500px; Background-color:black "></div>
</body>
<script type=" Text/javascript ">
var divs =document.getelementsbytagname ("div");
for (Var i=0;i<divs.length;i++) {
divs[i].addeventlistener (' click ', Function () {
alert ("DIVs" +i+ "was Click ")
},false)
}
</script>
Here cause I'll always be the last one, what's this for?
The closure remembers the reference to the variable, not the value of the variable at the time the closure was created.
How to solve it. Use immediate function
var divs=document.getelementsbytagname ("div");
for (var i=0;i<divs.length;i++) (function (n) {
divs[n].addeventlistener ("click", Function () {
alert ("DIVs "+n+" was click ")
},false)
}) (i)
Class Library Encapsulation
Another important use of the closure and instant function fine-grained applications is for the development of JavaScript class libraries, when we develop a class library, it is important not to want some unnecessary variables to pollute the global namespace, especially those temporary variables
such as: jquery
(function () {
var jquery=window.jquery=function () {
...
};
//...
}) ()
To ensure that sometimes the jquery object in the window is also destroyed, a variable is also given in the closure