据说招聘前端程序员的时候,js闭包是个面试官常常问的问题.因此我拿出时间来整理一下:javascript
啥是闭包?html
闭包是能读取其余函数内部变量的函数,js中能读取一个函数内部变量的只有该函数的后代函数,在函数的外部是访问不了函数的变量的.前端
须要操做某个函数的内部变量时,不能把全部的操做都放在函数内部,这样就须要内部函数做为一个桥梁,将函数的信息输送出来java
注意一点,在函数内部声明变量时必需要使用var,不然系统会认为你声明的是一个全局变量程序员
声明变量时,若是不写var,系统会认为声明的是window.a,即window对象的属性面试
闭包有啥用?安全
1.能够防止全局的命名空间被污染闭包
--若是要写一个累加器,不使用闭包的话,就必须定义一个全局的变量来接收模块化
var count = 0; function add(){ count++; console.log(count); }
//每次调用add函数count就会加1 add(); add(); add();
//这个函数若是count变量放在函数内部,每次调用函数时count都会被重置为0,不能达到累加的做用
//若是使用闭包就不会出现这一问题
2.便于模块化开发函数
使用闭包开发的项目各个功能都被封装到了各自的函数中,之间互不影响
3.安全性
将变量都变为私有的,只有经过内部函数才能访问函数的变量,可以提升成程序的安全性
闭包咋写啊?
上面的例子若是写成闭包的形式就是这样:
function add(){ var count = 0; function inner(){ count++; console.log(count); } return inner;
//将内部函数做为返回值返回 } var outer = add();//定义一个变量接收add函数的返回值 outer(); outer(); outer();
//在函数外add函数外直接访问count变量是不可能的,可是经过闭包就能够实现
闭包常常与for循环和匿名自调用函数结合:
<!DOCTYPE html> <html> <head> <title>模拟一个非诚勿扰的场景</title> <script type="text/javascript"> window.onload = function(){ var btn = document.querySelectorAll('.choiceArea>button'); function demo(){ for(var i=0;i<btn.length;i++){ //每次循环都将i做为一个参数赋值给j (function(j){ btn[j].onclick =function(){ alert("你的的选择是"+(j+1)+"号女嘉宾"); } }(i)); }; } demo(); } </script> </head> <body> 请选择你的心动女生:<br /> <form class="choiceArea"> <button>1号女嘉宾</button> <button>2号女嘉宾</button> <button>3号女嘉宾</button> <button>4号女嘉宾</button> <button>5号女嘉宾</button> </form> </body> </html>
闭包的缺点
正常函数执行结束以后会当即销毁,而闭包由于存在引用会一直存在在内存中,若是闭包过多就会在内存中占用大量资源,影响程序的性能.