主要分三部分说:
1、什么是闭包?2、闭包有什么好处?应用在哪里?javascript
第一个特色:能够是函数嵌套函数html
function fna(){ function fnb(){} }
第二个特色:内部函数能够引用外部函数的参数和变量java
function fna(){ var b=5; function fnb(){ console.log(b); } fnb(); } fna();
b变量都要被内部函数fnb()引用到,会一直驻扎在内存中,不会被垃圾回收的,也就是说参数和变量不会被垃圾回收机制所收回。
那么什么是js垃圾回收机制呢?闭包
function fna(){ var a=1; } fna();
例如,上面写了个普通函数fna(),当fna();执行完毕后变量a就不存在了,为了节省内存。
例1:函数
function fna(){ var a=5; function fnb(){ console.log(a); } return fnb; } var fnc=fna(); fnc(); //5
变量c就是返回的fnb函数,fnc()执行的时候 变量a并无消失,一直驻扎在内存中的,这时会弹出5的.这就是简单的闭包形式。code
好处:
1.但愿一个变量长期驻扎在内存当中
2.避免全局变量的污染htm
var a=1; function fna(){ a++; console.log(a); } fna(); //2 fna(); //3 console.log(a);//3
a是个全局变量,一直驻扎在内存中,依次执行会累加。索引
function fna(){ var a=1; a++; console.log(a); } fna(); //2 fna(); //2
若是把变量a设置为局部变量,每调用一次代码从新执行,调用后a就不存在,下次调用的时候a仍是1;那么怎么能作到a便是局部变量,a又能累计呢?
这就是闭包所能作到的。
例2:ip
function fna(){ var a=1; return function () { a++; console.log(a); }; } var fnb=fna(); fnb(); //2 fnb(); //3 console.log(a) //undfined
构成了函数嵌套函数,当外面的函数执行完毕后,内部函数依旧能够调用到变量a;内存
(function(){ console.log(1); })();
()放函数,函数声明就会变成函数表达式,再加()当即执行。
至此能够把例2中的代码改写一下.
var fna= (function () { var a=1; return function () { a++; console.log(a); } })(); fna();//2 fna();//3
var a=1在外面是调用不到,减小全局变量的污染,把内部函数变为私有的,
这也就是
3.变量私有
var aaa = (function(){ var a = 1; function bbb(){ a++; console.log(a); } function ccc(){ a++; console.log(a); } return { b : bbb, c : ccc } })(); //aaa.b(); //2 //aaa.c(); //3
在循环中直接找到对应元素的索引
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> <li>11111111111</li> <li>11111111111</li> <li>11111111111</li> </ul> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ console.log(i);//3 }; }; }; </script> </body> </html>
console.log(i)弹出3,为何呢?很明显,当循环执行结束的时候
aLi[i].onclick = function(){ console.log(i);//3 };
还没执行,当点击的时候才会执行,但此时i已经变成3了。能够利用闭包改写,能够把循环中的i看成个参数传进去,就以前所说的内部函数能够引用外部函数的参数和变量。
for(var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ console.log(i); }; })(i);
把i当成参数穿进去。除了这种写法还有另一种方式
for(var i=0;i<aLi.length;i++){ aLi[i].onclick = (function(i){ return function(){ console.log(i); } })(i);