闭包

有权访问另外一个函数作用域中变量的函数。
闭包是指那些能够访问自由变量的函数.自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。闭包=函数+函数能够访问的自由变量。
每一个函数都会拷贝上级作用域,形成一个作用域链条。
闭包:自由变量的查找,是在函数定义的地方,向上级作用域查找。不是在执行的地方。
闭包的变量存在堆中,即解释了函数调用之后为什么闭包还能引用到函数内的变量。
闭包的形成需要两个条件:

  • 闭包是在函数被调用执行的时候才被确认创建的。
  • 闭包的形成,与作用域链的访问顺序有直接关系。
  • 只有内部函数访问了上层作用域链中的变量对象时,才会形成闭包,因此,我们可以利用闭包来访问函数内部的
    变量。

    闭包,本质上是上级作用域内变量的生命周期,因为被下级作用域引用,没有得到释放,需要等到下级作用域
    执行完后才得到释放。

作用

  1. 独立作用域,避免变量污染
  2. 实现缓存计算结果
  3. 库的封装jQuery

运用

防抖节流
防抖:事件触发高频到最后一次操作,如果规定时间内再次触发,则重新计时。

1
2
3
4
5
6
7
8
9
10
11
function debounce(fn,delay=300){
let timer;//闭包引用外界变量
return function () {
consr args=arguments;
if (timer){
clearTimeout(timer);
}
timer = setTimeout(()= {
fn.apply(this,args);
}, delay);
};

模拟块级作用域

1
2
3
4
5
6
7
8
function OutPutNum(cnt){
(function () {
for (let i=0;i<cnt;i++){
alert(i);
}
})();
alert(i);
}

对象中创建私有变量

内存泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript 示例</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
#button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>

<h1>JavaScript 事件监听示例</h1>
<button id="button">点击我</button>

<script>
function fun() {
var element = document.getElementById("button");
var someResource = new Array(1000).join("*"); // 模拟一个超大资源
element.addEventListener("click", () => {
console.log(someResource);
});
}
fun();
</script>

</body>
</html>

解决方法:不再使用监听事件时通过removeEventListener移除监听