Closure is a difficulty and characteristic of Javascript language. Many advanced applications rely on closure.
Closures have three characteristics:
1. Function nested function
2. External parameters and variables can be referenced inside the function
3. Parameters and variables will not be recycled by the garbage collection mechanism
A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within a function and access the local variables of this function through the other function
Using closures has an advantage and a disadvantage, that is, local variables can reside in memory and avoid using global variables. Global variables are callable in every module, which is bound to be disastrous.
So it is recommended to use private, encapsulated local variables.
After the general function is executed, the local active object is destroyed, and only the global scope is saved in the memory. But the situation with closures is different!
Closure of nested functions:
function aaa() { var a = 1; return function(){ alert(a++) }; } var fun = aaa(); fun();// 1 执行后 a++,,然后a还在~ fun();// 2 fun = null;//a被回收!!
The above output result is 5;
Closures will always keep variables in memory, which will increase memory consumption if used improperly.
Garbage collection principle of JavaScript
(1). In JavaScript, if an object is no longer referenced, then the object will be recycled by GC;
(2) If two objects refer to each other and are no longer referenced by a third party, then the two objects that refer to each other will also be recycled.
So what are the benefits of using closures? The benefits of using closures are:
1. Want a variable to reside in memory for a long time
2. Avoid pollution of global variables
3. The existence of private members
1. Accumulation of global variables
<script> var a = 1; function abc(){ a++; alert(a); } abc(); //2 abc(); //3 </script>
<script> function abc(){ var a = 1; a++; alert(a); } abc(); //2 abc(); //2 </script>
So how can we make variable a both a local variable and accumulative?
3. Accumulation of local variables (what closures can do)
<script> function outer(){ var x=10; return function(){ //函数嵌套函数 x++; alert(x); } } var y = outer(); //外部函数赋给变量y; y(); //y函数调用一次,结果为11 y(); //y函数调用第二次,结果为12,实现了累加 </script>
Function declaration and function expression in js:
In js we can declare a function through the keyword function:
<script> function abc(){ alert(123); } abc(); </script>
We can also turn this statement into an expression through a "()":
<script> (function (){ alert(123); })(); //然后通过()直接调用前面的表达式即可,因此函数可以不必写名字; </script>
4. Modular code to reduce pollution of global variables
<script> var abc = (function(){ //abc为外部匿名函数的返回值 var a = 1; return function(){ a++; alert(a); } })(); abc(); //2 ;调用一次abc函数,其实是调用里面内部函数的返回值 abc(); //3 </script>
5. The existence of private members
<script> var aaa = (function(){ var a = 1; function bbb(){ a++; alert(a); } function ccc(){ a++; alert(a); } return { b:bbb, //json结构 c:ccc } })(); aaa.b(); //2 aaa.c() //3 </script>
6. Directly find the index of the corresponding element in the loop
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ //当点击时for循环已经结束 alert(i); }; } } </script> </head> <body> <ul> <li>123</li> <li>456</li> <li>789</li> <li>010</li> </ul> </body> </html>
7. Rewrite the above code using closure:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i); } }; </script> </head> <body> <ul> <li>123</li> <li>456</li> <li>789</li> </ul> </body> </html>