JavaScript Object-oriented closures
Learning JavaScript for some time, I made the following summary of the closure, if there is something wrong, please point out, I 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 = foo (); alert (r1 + ' \ n ' + r2); If you use return to return data within a function, it is theoretically not access to a data , because when the function is run it allocates memory space, and when the function is called, the data is 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 ();//function call num is the only var r1 = fn (); var r2 = fn (); alert (r1 + ' \ n ' +r2)//FN is a function defined within a function, so at execution time you can access num in the scope of the previous level, Therefore, on the outermost side, the only num can be accessed 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
function Foo () {var o = {num:123}; return 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
function Foo () {var o = new Function (' Alert (123) '); return o;} var fn = Foo (), equivalent to var fn = new Functon (' Alert (123) '); alert (FN);//123
Executes a function that returns an array to the function
function func () { var m = math.random (); var n = math.random (); return [ function () {return m;} function () {return n;} ]} 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
function func () { var m = math.random (); var n = math.random (); return { get_m:function () {return M;}, get_n:function () {return N;} }; } 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
function Foo () { var obj = new Object ();//This can also be written as var obj = {};? ? var num; Obj.get_num = function () { return num;}; Obj.set_num = function (v) { num = v;}; return obj;} var o = Foo (); Console.log (O.get_num ());//undefinedconsole.log (O.set_num (one));//undefinedconsole.log (O.get_num (11) );//11
The second type of notation
function Foo () { var num; return { get_num:function () { return num; }, set_num:function (v) { num = v; } }; } var o = Foo (); Console.log (O.get_num ()); Undefined console.log (o.set_num);//undefined Console.log (O.get_num ());//11
This has a variable for the above function
function Foo () { var num; return { _num:num,//assignment operation Set_num:function (v) { num = v; } }; } Equivalent to function Foo () { var num; var obj = {}; Obj._num = num;//The num declared above and the _num variable at this time are different obj.set_num = function (v) { num = v; }; return obj; } var o = Foo (); Console.log (O._num); Undefined console.log (O.set_num (one)); Undefined console.log (o._num); Undefined data not being taken out
Applications for closures: implementing private and cached data
The Fibonacci sequence of the closure case
Functional with no closures
var count = 0; var fib = function (n) { count++; if (n< 0) throw new Error (' Do not allow negative numbers '); if (n = = = 0| | n = = = 1) return 1;// return fib (n-1) +fib (n-2); Return Arguments.callee (n-1) + Arguments.callee (n-2); } Console.log (FIB (+)); Console.log (count); The number of entries for 1th, 2, 4, 8, 16, 32 respectively is 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
var count = 0; var fib = (function () { var arr = []; return function (n) { count++; if (n < 0) throw new Error (' Do not allow negative numbers '); var res = arr[n];//Cache data to determine if there is no data if (res!== undefined) { return res; } else { if (n = = = 0| | N ===1) { res = 1; } else{ res = fib (n-1) +fib (n-2); } } Arr[n] = res; return res; } }) (); Console.log (FIB); Console.log (count);//199
The second type of notation
var count = 0; var fib = (function () { var arr = []; return function (n) { count++; Return Feibo (arr,n); } }) (); function Feibo (arr,n) { if (N < 0) throw new Error ("No negative numbers allowed"); var res = arr[n]; if (res! = undefined) { return res; } else{ if (n = = 0 | | n = = = 1) { res = 1; } else{ res = fib (n-1) + fib (n-2); } } Arr[n] = res; return res; } Console.log (FIB); 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
var fib = function (n) { var res = fib[N]; Take the if (res!== undefined) {return res) to the function name first, or else { ///if 1 or 0 returns 1 to RES //Otherwise the recursive result is given to res;< C7/>if (n = = 0 | | n = = 1) { res = 1; } else { res = Arguments.callee (n-1) + Arguments.calle E (n-2); } fib[n] = res; The result of the calculation is put into the array, then the next recalculation //time can be directly used, you do not have to recalculate fib.len++;//each assignment after the return res; } ; Fib.len = 0;//Adds an attribute Console.log (fib) to the function; Console.log (Fib.len)//101
JavaScript Object-oriented closures