闭包的理解及应用

211 阅读2分钟

闭包

  • 闭包就是指有权访问另一个函数作用域中的变量的函数
  • MDN 上面这么说:闭包是一种特殊的对象。

闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。闭包的注意事项
通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,
这个函数的作用域就会一直保存到闭包不存在为止。

我们首先知道闭包有3个特性:
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收

优点:
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗

闭包的缺点就是常驻内存会增大内存使用量,并且使用不当很容易造成内存泄露。
如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,
因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

// 防抖  
function debounce(fn, wait) {  
let timeout = null;  
return function() {  
let context = this;  
let args = arguments;  
if (timeout) clearTimeout(timeout);  
let callNow = !timeout;  
timeout = setTimeout(() => {  
timeout = null;  
}, wait);  
if (callNow) fn.apply(context, args);  
};  
}  
  
// 使用示例  
window.addEventListener('resize', debounce(function() {  
console.log('窗口大小已改变');  
}, 250));  
  
// 截流  
function throttle(fn, wait) {  
let previous = 0;  
return function() {  
let context = this;  
let args = arguments;  
let now = new Date();  
if (now - previous > wait) {  
fn.apply(context, args);  
previous = now;  
}  
};  
}  
  
// 使用示例  
window.addEventListener('scroll', throttle(function() {  
console.log('滚动事件被触发');  
}, 200));