闭包的理解(防抖,节流函数)
闭包理解,闭包在项目中的应用
闭包:有权访问另一个函数作用域中的变量的函数,也就是一个函数可以访问员另一个函数内部的局部变量
作用:延展了变量的作用域范围,所以没有处理好的话也可能导致内存泄漏
简单案例:
function Fn() {
let n = 0;
return function () {
//访问另一个函数作用域内的变量
console.log(n);
};
}
var f = Fn(); //保存命名一个变量引用返回的匿名函数
f(); //闭包
闭包的一些应用,比如利用解决for利用var声明没有块级作用域问题
for (var i = 0; i < 5; i++) {
setTimeout(
function timer(j) {
console.log(j);
},
i * 100,
i
);
}
//输出 1,2,3,4
//由于传入参数i,也就延伸变量i的作用域范围,setTimeout内部函数就会保存了i作为参数使用,而就不会被回收机制回收,会保存在setTimeout中,所以会正常输出(核心还是变量作为参数延伸了作用范围)
另一种利用闭包解决方法(最简单的let就不做说明了,这里主要是体现闭包)
//使用立即执行函数来传递参数i,延申变量作用范围
for (var i = 0; i < 5; i++) {
(function (i) {
//内部箭头函数与普通函数均可
setTimeout(() => {
console.log(i);
}, 0);
})(i);
}
防抖:好比回城,打断(触发事件)之后重新计时,淘宝搜索,窗口调整大小(控制函数执行次数)
节流:好比治疗,事件间隔内无法再次触发,事件间隔内只执行一次,防止重复请求,反复加载等,事件间隔之后可重新触发
//防抖中的闭包
const button = document.querySelector('button');
function click(){
console.log('点击');
}
function debounce(fuc,delay){
let timer = null;
return function(){
//let timer = null(定义变量名在这是错误的,无法达到重新计时的作用,无法清除上一次设置的延时,因为每一个操作都是独立的,只是清除重建的操作)
//将timer设置在函数之外,这里就体现了闭包的作用,这里的清除timer是上一次设timer=setTimerout的作用范围延伸)
//触发事件之后重新计时
clearTimeout(timer)
//核心增加延时效果起到防抖作用(优化:使用头函数口可以优化函数指向,指向button,而不是指向window)
let timer = setTimeout(function(){
func();
},delay)
//let timer = setTimeout(()=>{
//可能接收参数
//func(argument);
//},delay)
}
}
//点击之后执行(传入回调函数和时间)
button.addEventListener('click',debounce( click , 1000 ));
在这也扩展以下节流,以下是品优购轮播项目中的应用
节流就达到了在时间间隔内无法再次触发,治疗
//节流案例
var timer = null;
var img = document.querySelector("img");
document.addEventListener("mousemove", function (e) {
//flag(timer)为任何值输出都是true ,除了null 0 undefined NaN
if (timer) {
return;
}
timer = setTimeout(function () {
var x = e.clientX; //page X/Y 也可以
var y = e.clientY;
img.style.left = x + "px"; //容易忽略单位问题
img.style.top = y + "px"; //容易忽略单位问题
timer = null;
}, 300);
//
});
//节流
function throttle(func, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
if (!timeout) {
//可以使用箭头函数
timeout = setTimeout(function(){
timeout = null;
func.apply(context, args)
}, wait)
}
}
}

浙公网安备 33010602011771号