闭包的理解及应用
闭包
- 闭包就是指有权访问另一个函数作用域中的变量的函数
- 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));