闭包的含义和作用
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可以即从外部获得变量c
function outer1(){
let c = 99;
//将变量返回到内部函数中
return function inner1(){
return c;
}
}
let closure = outer1();
let c1 = closure() // 99
用闭包来解决在循环中遇到的相关问题
当给多个元素绑定点击事件时使用循环遍历绑定的方法,点击绑定事件是异步回调的方法,所以会等到循环结束后才将i返回,以下会导致的问题就是无论点击哪个元素都只会打印3
<html>
<div id='div0'>div0</div>
<div id='div1'>div1</div>
<div id='div2'>div2</div>
<script>
for(var a==0;a<3;a++){
var div = document.getElementById('div'+n).addEventListener('click',function(){
console.log(n)
})
}
</script>
</html>
使用闭包,封装成一个独立的立即执行的匿名函数,将每次循环的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)
}
注意事项
使用闭包会导致内存外泄,因为当函数执行完后里面的变量并没有被垃圾清除机制清理,过多使用闭包会影响性能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。