Learning JavaScript for some time, after the guidance of the master, the closure of their own to make the following summary, if there is something wrong, please point out, appreciate it!
To understand closures, you must first understand the special variable scope of JavaScript.
The scope of a variable is nothing more than two kinds: global variables and local variables.
The special point of the JavaScript language is that the global variables can be read directly inside the function, and local variables within the function cannot be read outside the function.
Note that when declaring variables inside a function, be sure to use the var command. Otherwise, it becomes a global variable.
In short, closures are a protected variable space.
Closure case
Functon () { var num = math.random; return num; } var res = foo (); In this cannot directly access the function internal variable num, can only indirectly access var r1 = foo (); var r2 =+ ' \ n ' + R2), if using return returns the data within the function, it is theoretically not access to a data, because the function will allocate memory space, when the function is called, the data will be created again
To solve the above problem, get the same data how to operate
function () { var num = Math.random (); return function () { return num; }} var fn = foo (); // var R1 = FN (); var R2 = FN (); alert (r1 + ' \ n ' +R2) // FN is a function defined within a function, Then, at execution time, you have access to NUM in the previous scope, and therefore, at the outermost level, you can access the unique num indirectly. here is the use of closures, this time to protect the data of my role .
The nature of the function: an instance of the functions, also an object.
Executes a function that returns an object to the function
functionvar o = {num:123return o;} var obj = Foo (); alert (obj.num);//123
When a function is called, an object is created inside the function
A reference to the object is stored in O, and return is a copy of the data in O and returned
The returned result is received by obj, at which point obj stores a reference to the object
Executes a function that returns a function to the function
functionvarnew function (' Alert (123) 'return o;} var fn =new Functon (' Alert (123) '); alert (FN); // 123
Executes a function that returns an array to the function
functionfunc () {varm =Math.random (); varn =Math.random (); return [ function() {returnm;} function() {returnN;} ]}//var Fns = func ();//var m1 = fns[0] ();//var n1 = fns[1] (); //Alert (m1 + ', ' + N1); //var m2 = fns[0] ();//var n2 = fns[1] (); //Alert (M2 + ', ' + N2);
The results in the above two sets of data are the same,
The advantages of arrays reflect the order of the data. Multiple data can be sorted
But in complex data, the number of data is no longer an advantage
You can use objects to improve on these functions
functionfunc () {varm =Math.random (); varn =Math.random (); return{get_m:function(){returnm;}, Get_n:function(){returnN;} }; }//var obj = func ();//var M1 =obj.get_m ();//var n1 = Obj.get_n (); //Alert (m1 + ', ' + N1);
Closure case call a function provides two methods for assigning and reading num
The first form of a notation
functionFoo () {varobj =NewObject ();//This can also be written as var obj = {};?? varnum; Obj.get_num=function(){ returnnum;}; Obj.set_num=function(v) {num =v;}; returnobj;} varo =Foo (); Console.log (O.get_num ());//undefinedConsole.log (O.set_num (11));//undefinedConsole.log (O.get_num (11));// One
The second type of notation
functionFoo () {varnum; return{get_num:function () { returnnum; }, Set_num:function(v) {num=v; } }; } varo =Foo (); Console.log (O.get_num ()); //undefinedConsole.log (O.set_num (11));//undefinedConsole.log (O.get_num ());// One
This has a variable for the above function
functionFoo () {varnum; return{_num:num,//assignment operation Set_num:function(v) {num=v; } }; } //equivalent to the following function functionFoo () {varnum; varobj = {}; Obj._num=num;//The NUM declared above and the _num variable at this time are different obj.set_num=function(v) {num=v; }; returnobj; } varn \Foo (); Console.log (O._num); Undefined Console.log (O.set_num (11)); Undefined Console.log (o._num); //undefineddata not being taken out
Applications for closures: implementing private and cached data
The Fibonacci sequence of the closure case
Functional with no closures
varCount = 0; varFIB =function(n) {count++; if(n< 0)Throw NewError (' Do not allow negative numbers ')); if(n = = 0| | n = = 1)return1;//return fib (n-1) +fib (n-2); returnArguments.callee (n-1) + Arguments.callee (n-2); } console.log (Fib (16)); Console.log (count); //The numbers of 1th, 2, 4, 8, 16 and 32 respectively were calculated as 1, 3, 9, 67, 3193,7049155
From the calculation of the number of times can be seen that the loss of performance is very serious, then the closure can solve the problem is that the data has been calculated to cache
varCount = 0; varFIB = (function(){ vararr = []; return function(n) {count++; if(N < 0)Throw NewError (' Do not allow negative numbers ')); varres = arr[n];//cache data to determine if there is no data if(Res!==undefined) { returnRes; } Else { if(n = = 0| | N ===1) {res= 1; } Else{res= Fib (n-1) +fib (n-2); }} Arr[n]=Res; returnRes; } })(); Console.log (FIB (100)); Console.log (count);//199
The second type of notation
varCount = 0; varFIB = (function(){ vararr = []; return function(n) {count++; returnFeibo (arr,n); } })(); functionFeibo (arr,n) {if(N < 0)Throw NewError ("No negative numbers allowed"); varres =Arr[n]; if(Res! =undefined) { returnRes; }Else{ if(n = = 0 | | n = = 1) {res= 1; }Else{res= Fib (n-1) + fib (n-2); }} Arr[n]=Res; returnRes; } console.log (Fib (100)); Console.log (count);
The advantages of closures can be seen from the above formula;
Expansion: When it comes to data caching it can also be used without closures, the following function is not related to closures
varFIB =function(n) {varres = fib[N];//take the function name first if(Res!==undefined) { returnRes; } Else { //returns 1 to res if 1 or 0 //otherwise the recursive result is given to Res; if(n = = 0 | | n = = 1) {res= 1; } Else{res= Arguments.callee (n-1) +Arguments.callee (n-2 ); } fib[N]=Res; //put the result of the calculation in the array, and the next time you recalculate the //when you can use them directly, you don't have to recalculatefib.len++;//once each assignment is complete returnRes; } }; Fib.len= 0;//add a property to a functionConsole.log (FIB (100)); Console.log (Fib.len)//101
About JavaScript Object-oriented closures