什么是闭包
简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。就是能够读取其他函数内部变量的函数。
简单的闭包例子
毕竟简单常见的就是内部返回一个函数
function closure(){
var a = 0
return function(){
return a
}
}
var b = closure()
console.log(b()) //输出:1
for(var i = 0;i<5;i++){
(function(i){
setTimeout(function(){
console.log(i + ' ')
},1000)
}(i))
}
闭包的优缺点
优点
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突;
var one= "one";
var oneNum= function(){
var one= "1";
return function(){
return one;
}
}()
console.log(one);//"one"
console.log(oneNum());//"1"
②做缓存
③匿名自执行函数可以减少内存消耗 (function(){}){}
缺点
①内存泄漏
解决
①及时释放闭包:手动调用闭包函数,并将其返回值赋值为null
②使用立即执行函数
其他应用
防抖
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果延时还没执行,又触发了就重新开始延时。
function debounce(fn, delay) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}
节流
当持续触发事件时,保证在一定时间内只调用一次事件处理函数。
function throttle (func ,wait){
let context ,args,timeout;
return function(){
context = this
args = arguments
if(!timeout){
timeout = setTimeout(){
func.apply(context,args)
timeout = null
}
}
}
}
---------------------------
const throttle = (fn, interval) => {
var enterTime = 0; //触发的时间
var gapTime = interval || 300; //间隔时间,如果interval不传,则默认300ms
return function () {
var context = this;
var backTime = new Date(); //第一次函数return即触发的时间
if (backTime - enterTime > gapTime) {
fn.call(context, arguments);
enterTime = backTime; //赋值给第一次触发的时间,这样就保存了第二次触发的时间
}
};
}
区别
防抖是将多次执行变为最后一次执行,一个时间内你点多次也是按最后一次执行;节流是将多次执行变为每隔一段时间执行,你点多次也不管,就等我执行完了才说。
使用场景
防抖:
·页面resize事件,页面适配时,根据最终呈现的页面情况进行dom渲染
·频繁点赞取消,疯狂点击领奖按钮什么的,避免那些短时间频繁请求
节流:
·onscroll等这些频繁触发的函数,如获取滚动条的位置,然后执行下一步动作;
·鼠标不断点击触发,mousedown(单位时间内只触发一次);
·搜索框input事件,例如要支持输入实时搜索
面试可能遇到的问题
1.一般面试会问什么是闭包,或者说说一下对闭包的理解啥的
2.问完闭包,可能会让你说举个闭包的例子,一般会问到对应的作用域相关的题目,偶尔会问到JS的垃圾回收机制。
3.可能会问到闭包的用处,以及什么时候会用到闭包,闭包有什么缺点
4.会遇到一些this相关打印类型的面试题,或者是与定时器相结合。