闭包知识浅谈
程序员文章站
2022-03-22 10:27:02
什么是闭包?闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。闭包要满足的条件:【1】访问所在作用域;【2】函数嵌套;【3】在所在作用域外被调用function func(){ var n = 0; // n是func函数的局部变量 console.log(n,'func');// function closur...
什么是闭包?
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包要满足的条件:
【1】访问所在作用域;
【2】函数嵌套;
【3】在所在作用域外被调用
function func(){
var n = 0; // n是func函数的局部变量
console.log(n,'func');//
function closure() { // closure是func函数的内部函数,是闭包
n += 1; // 内部使用了外部函数中的变量n
console.log(n,'closure');
}
return closure;
}
var counter= func();//这里会调用一次func函数,打印 0,'func'
counter(); //调closure 打印 1,'closure'
counter(); //调closure 打印 2,'closure'
counter(); //调closure 打印 3,'closure'
闭包的特点:
让外部访问函数内部变量成为可能;
局部变量会常驻在内存中;
可以避免使用全局变量,防止全局变量污染;
会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
闭包的坑点:
坑点1:引用的变量可能已经发生变化
坑点2:this指向问题
坑点3:内存泄漏问题
经典案例:闭包与定时器
按照预期它应该依次输出1-10,而结果它输出了十次11,这是为什么呢?原来由于js是单线程的,所以在执行for循环的时候定时器setTimeout被安排到任务队列中排队等待执行,而在等待过程中for循环就已经在执行,等到setTimeout可以执行的时候,for循环已经结束,i的值也已经变成11,所以打印出来十个11,那么我们为了实现预期结果应该怎么改这段代码呢?(ps:如果把for循环里面的var变成let,也能实现预期结果)
引入闭包来保存变量i,将setTimeout放入立即执行函数中,将for循环中的循环值i作为参数传递,1秒后同时打印出1-10
闭包的应用:
给li添加点击事件,输出li对应的索引
<ul>
<li>11111</li>
<li>22222</li>
<li>333333</li>
<li>444444</li>
<li>5555555</li>
</ul>
var list = document.querySelectorAll('li');
for (var i = 0; i < list.length; i++) {
(function(i) { //var i=0-4
list[i].onclick = function() {
alert(i); //0-4
}
})(i);
}
本文地址:https://blog.****.net/qq_39264561/article/details/107522983