首页 > 代码库 > 闭包及其作用
闭包及其作用
闭包:有权访问其他函数内部变量的函数,在一个函数内部创建一个函数,就形成了闭包,闭包的参数和变量不会被垃圾回收机制回收。闭包可以避免全局变量的污染。
使用场景:
1.闭包的经典应用:绑定事件
假如页面上有5个div,我们通过for循环来给每个div绑定一个事件,每点击一次输出它的索引值。如果没有使用闭包,在循环内部给每个节点添加事件,发现点击后每次输出的值都是一样的。因为onclick事件时异步触发的,当事件触发的时候for循环早就结束了。此时变量i的值是5,。解决办法就是在闭包的帮助下,把每次循环的i值包裹起来:使用立即执行函数将i值作为参数传递进去后再绑定事件
var list=document.getElementById("list"); for (var i = 0; i < list.length; i++) { (function(i){ list[i].onclick=function(){ console.log(i); } })(i); }
2,封装变量:闭包可以帮助把一些不需要暴露在全局的变量封装成私有变量。
在大型项目当中,为了防止命名冲突,一般会把相应的代码用闭包的形式包裹起来,避免暴露在全局作用域下
假如有一个函数接受number类型的参数并返回这些参数的乘积,你应该怎么做。
第一步你应该会写出下面的代码:
var mult=function(){ var a=1; for (var i = 0; i < arguments.length; i++) { a=a*arguments[i]; } return a; };
优化代码:假如缓存机制,如果参数相同直接返回这个缓存后的值
var cache = {}; var mult = function() { var args = Array.prototype.join(arguments, ‘,‘); if (cache[args]) { return cache[args]; } else { var a = 1; for (var i = 0; i < arguments.length; i++) { a = a * arguments[i]; } return cache[args] = a; } }
继续优化:注意到cache这个变量只在这个函数内部被使用,与其让其和mult函数一起暴露在全局作用域下,还不如把它封装在函数内部,
var mult = (function() { var cache = {}; //把原先的cache封装在函数的内部,这样可以减少页面内的全局变量 return function() { var args = Array.prototype.join(arguments, ‘,‘); if (cache[args]) { return cache.args } else { var a = 1; for (var i = 0; i < arguments.length; i++) { a = a * arguments[i]; } return cache[args] = a; } } })(); //立即执行函数后return一个function
提炼函数是代码重构中的一种常见技巧。如果在一个大函数中有一些代码块能够独立出来,那么我们将它封装在一个小函数当中,这样有助于代码复用,如果同时小函数有个好名字,那么也起到注释的作用。如果小函数不在程序的其他地方使用,那么将它放在闭包当中。
var mult = (function() { var cache = {}; //把原先的cache封装在函数的内部,这样可以减少页面内的全局变量 var caculate = function() { var a = 1; for (var i = 0; i < arguments.length; i++) { a = a * arguments[i]; } return a; } return function() { var args = Array.prototype.join(arguments, ‘,‘); if (cache[args]) { return cache[args]; } cache[args]=caculate.apply(null,arguments);//null指默认的宿主对象 } })();
3.延续局部变量的寿命
用img对象来进行数据上报时,把img变量用闭包封闭起来,因为在低版本的浏览器用report函数上报数据时存在bug,会丢失数据。
因为img是局部变量,函数执行完毕后局部变量随即被销毁,以至于来不及发出http请求,导致数据丢失。
var report=(function(){ var imgs=[]; return function(src){ var img=new Image(); imgs.push(img); img.src=src; } })(); report("url");//数据上报
闭包及其作用