JS 谈谈你对闭包的理解
目录
一、闭包的概念和理解
二、闭包的使用场景
1.回调
2.setTimeout回调函数传参
3.防抖节流函数的应用(详情见以下链接)
4.柯里化函数
5.创建私有变量(JavaScript中声明私有变量的关键字,可以利用闭包的特性声明 私有变量)
三、闭包的优缺点
一、闭包的概念和理解
闭包就是在一个内层函数中访问到其外层函数的作用域
在
JavaScript
中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁
示例代码
function fn() {
let name = 'zs';
function getName() {
// 此时就形成了闭包,在内层函数中访问到外层函数的作用域
alert(name);
}
getName();
}
fn();
二、闭包的使用场景
1.回调
定义行为,然后把它关联到某个用户事件上(点击或者按键)。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件。
利用了闭包的特性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<a href="#" id="size-16">16</a>
<a href="#" id="size-30">30</a>
<a href="#" id="size-40">40</a>
<script>
function changeFontSize(size) {
return function () {
document.body.style.fontSize = size + 'px';
};
}
// 返回的size12,size14,size16都是函数
var size16 = changeFontSize(16);
var size30 = changeFontSize(30);
var size40 = changeFontSize(40);
// 分别绑定点击事件
document.getElementById('size-16').onclick = size16;
document.getElementById('size-30').onclick = size30;
document.getElementById('size-40').onclick = size40;
</script>
</body>
</html>
2.setTimeout回调函数传参
setTimeout的第一个参数是执行回调函数,第二个参数是延时时间
原生的setTimeou传递的第一个函数不能带参数,通过闭包可以实现传参效果
以下示例一秒后输出1
function fn1(x) {
return function fn2() {
console.log(x);
};
}
let fn = fn1(1);
setTimeout(fn, 1000);
3.防抖节流函数的应用(详情见以下链接)
防抖函数
JS防抖函数的实现(巨详细,秒懂)_~black-的博客-CSDN博客在一定的时间间隔内,如果没有再次触发该函数,那么才会去执行函数体内的代码(例如发送网络请求)。https://blog.csdn.net/qq\_63299825/article/details/130862307节流函数
JS 节流函数的实现_~black-的博客-CSDN博客限制一个函数在一定时间内只能执行一次我自己的理解: 节流函数就是 在规定时间内 不管触发几次该事件,都只执行第一次,第一次触发事件等待delay后,事件执行。timer置为null,再次循环。https://blog.csdn.net/qq\_63299825/article/details/130871293
4.柯里化函数
把接受多个参数的函数转换成接受一个单一参数的函数, 当多个参数中 有参数相等时,就实现了闭包和重用的效果。
代码示例如下:
function getArea(width, height) {
return width * height;
}
const area1 = getArea(10, 20);
const area2 = getArea(10, 30);
const area3 = getArea(10, 40);
// 通过上面代码可以发现,第一个参数宽度width都相等。不难发现,可以利用柯里化函数就是 优化
function getArea(width) {
return (height) => {
return width * height;
};
}
// 通过调用getArea(10)就返回了 宽度width为10的函数,再次调用传入高度height即可得到面积
const getWidthArea = getArea(10);
const area1 = getWidthArea(20);
const area2 = getWidthArea(30);
const area3 = getWidthArea(40);
5.创建私有变量(JavaScript中声明私有变量的关键字,可以利用闭包的特性声明 私有变量)
每次调用其中一个increase()时,通过改变这个变量的值,会改变这个闭包的词法环境,不会影响另一个闭包中的变量
function fn() {
var sum = 0;
return {
increase() {
sum++;
return sum;
},
};
}
let result1 = fn();
console.log(result1.increase()); //1
console.log(result1.increase()); //2
console.log(result1.increase()); //3
// result2 和 result2 的作用域互不影响,和 result2使用的sum互不影响即私有变量sum,result1
let result2 = fn();
console.log(result2.increase()); //1
三、闭包的优缺点
优点变量长期驻扎在内存中,可以重复使用变量
2:闭包可以实现局部变量,避免全局变量的污染
3:可用于声明私有函数和变量
缺点:1.滥用闭包会造成内存泄露
2.性能损失大
还没有评论,来说两句吧...