- 什么是闭包?
闭包本质上是一种函数,所以闭包技术也是函数技术的一种。
闭包的花式比较多,用法也比较灵活,一般开发人员在学习闭包的时候也总会遇到瓶颈,主要因为闭包技术的分界线不明显,几乎无法用同一种特点来区分。
当一个嵌套的内部函数引用了它以外的函数的变量(函数)时就产生了闭包。
⚠️这里有两个点:一个是必须嵌套,一个是变量(函数)的引用。
- 产生闭包的条件?
再强调一遍:当一个嵌套的内部函数引用了外部函数的变量(函数)时就产生了闭包。
3.常见的闭包使用形式?
3.1. 将函数作为另一个函数的返回值。
例如:
3.2. 将函数的形参作为实参传递给另一个函数。
4.闭包的作用?
先来思考两个问题
4.1)函数执行完,函数内部声明的局部变量是否还存在?
一般是不存在的,但是闭包的作用之一是:延长局部变量的生命周期(即是函数内部声明的局部变量仍然存活于内存中)
4.2)函数外部能直接访问函数内部的变量吗?
不能,但是闭包的又一个作用就是可以让函数外部访问函数内部的变量
关于闭包延长局部变量的生命周期引申出:
4.3)垃圾回收机制即执行环境负责管理代码执行过程中使用的内存
4.4)循环引用
// The div has a reference to the event handler via its 'onclick' property
// The handler also has a reference to the div since the 'div' variable can be accessed within the function scope
// This cycle will cause both objects not to be garbage-collected and thus a memory leak.
类似于
\
建议写法
5.闭包的应用场景
5.1 模块封装
定义js模块,将所有的数据和功能都封装在一个函数内部(私有的),只像外部暴露一个包含多个方法的对象或者函数,模块的使用者只需调用对外暴露的对象调用方法来实现对应的功能。
比如:
5.2函数防抖
Window.onresize = throttle(
function(){
console.log(‘清清浅浅')
}
,200
)
function throttle(fn, time){
var timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(fn, time)
}
}
5.3高级排他
window.onload = function () {
let allLis = document.getElementsByTagName('li');
let preSelectIndex = 0;
for (let i = 0; i < allLis.length; i++) {
(function (i) {
let li = allLis[i];
li.onmouseover = function () {
allLis[preSelectIndex].className = '';
this.className = 'active';
preSelectIndex = i;
};
}(i));
}
};
6.闭包的缺点
函数执行完后,函数内的局部变量没法释放,占用内存时间会变长,容易造成内存泄漏。 这里又要引申出两个概念,内存泄漏,和内存外溢。blog.csdn.net/jie11756234…
一般来说,内存泄漏是在堆内存中。
前端如何查看内存占用