闭包的含义和作用
1、根据JavaScript作用链,只能在内部访问到外部函数,通过闭包外部也可以访问内部变量。
2、js有垃圾清理机制,当一个对象使用后会自动清理,闭包可以使变量一直保存在内存中不会被清理。正常情况下的访问 inner内部函数可以访问到变量a,但是outer访问不到inner的变量b
`function outer (){let a = 1;function inner(){ let b = 2; console.log(a); //1}
}
`使用闭包可以当函数执行完后变量仍然保持,将c保存到返回的inner1函数里,当outer1执行完后,c并不会被销毁而是返回到inner函数中。调用outer1()后,返回了inner1赋值给closure。再执行closure可以即从外部获得变量cfunction outer1(){ let c = 99; //将变量返回到内部函数中 return function inner1(){ return c; }}let closure = outer1();let c1 = closure() // 99
用闭包来解决在循环中遇到的相关问题
当给多个元素绑定点击事件时使用循环遍历绑定的方法,点击绑定事件是异步回调的方法,所以会等到循环结束后才将i返回,以下会导致的问题就是无论点击哪个元素都只会打印3
div0div1div2
使用闭包,封装成一个独立的立即执行的匿名函数,将每次循环的i作为参数传进去,这样就可以在执行的时候取到当前i的值而不是循环结束后的值,分别点击div都是打印的是0,1,2
for(var i=0;i<3;i++){ (function(n){ var div = document.getElementById('div'+n).addEventListener('click',function(){ console.log(n) }) })(i)}
同理setTimeout也是异步回调,如果没有使用闭包将它包裹会打印三次3
function(){ for(var i=0;i<3;i++){ setTimeout(()=>{ console.log(i) },0) }}
使用闭包后分别打印出0,1,2,3,4,5
for(let n=0;n<6;n++){ (function(m){ setTimeout(()=>{ console.log(m) },0) })(n)}
注意事项
使用闭包会导致内存外泄,因为当函数执行完后里面的变量并没有被垃圾清除机制清理,过多使用闭包会影响性能。