什么是闭包?
简单来说就是只要一个作用域访问到了另一个函数内部的局部变量就会产生闭包,被访问的局部变量所在的函数就称为闭包函数
function fn(a) {
// 参数a 这个参数a是不会被销毁的(缺点:内存占用)
return function () {
// 访问到这个a
console.log(a);
}
}
fn('hello')()//调用内部函数,会打印出hello
//这就是一个简单的闭包
闭包的核心概念
- 函数里面嵌套函数,可以多次嵌套,返回值为函数
- 内部函数可以调用外部函数的内容 作用域链
- 里面的参数和变量不会被垃圾回收机制回收
- 闭包的主要作用:延伸了变量的作用范围
闭包能做的事情
闭包的功能有:1.防抖 2.节流 3. 闭包的一种写法(函数柯里化)
调用闭包函数的执行规律
function fn1() {
let i = 0;
return function () {
i++
return i
}
}
console.log(fn1()());// 1 每次从0开始 结果就是1
console.log(fn1()());// 1
console.log(fn1()());// 1
let a = fn1() //调用一次 i = 0
console.log(a());// i = i++ ==>1
console.log(a());// i = i++ ==>2
console.log(a());// i = i++ ==>3
防抖功能说明及代码实现
防抖就是避免函数的重复调用 只执行一次;
比方说:电梯的开门时间为十秒,如果十秒内有人出入,那么电梯关门的时间又会重新从十秒钟倒计时,当十秒内没人经过电梯才会关门运行,这就好比我们的防抖功能,我们定义一个延时器,当我们事件触发延时器开始倒计时,如果在延时器倒计时过程中我们频繁触发事件,每次触发事件都会重新进入倒计时,只有当延时器运行完之后才会调用函数,这就避免了我们重复触发事件导致的函数重复调用。
function antishake(func, wait) {//传入参数 为执行的方法 间隔的时间
let timer = null; //声明延时器对象为空
return function () {
clearTimeout(timer) //清除延时器
timer = setTimeout(() => {//延时器调用
func()
}, wait)//区间内进来的只有一次执行
}
}
// 1.用变量接收的方式来调用延时器
//定义变量
let antishake1 = antishake(function () {
console.log('hello');
}, 1000)
document.querySelector('div').onmouseenter = function () {
antishake1() //调用延时器
}
//2.直接把函数作为参数调用方式 ,前面有讲到闭包的代码调用规则,我们防抖只需要传入一次参数,因为我们重复调用的是内部函数
document.querySelector('div').onmouseenter = antishake(function () {
console.log('hello');
}, 1000)