开源
个人开源的leno-admin
后台管理项目,前端技术栈:reactHooks
、ant-design
;后端技术栈:koa
、mysql
、redis
,整个项目包含web端
、electron客户端
、mob移动端
、template基础模板
,能够满足你快速开发一整套后台管理项目;如果你觉得不错,就为作者点个✨star
✨吧,你的支持就是对我最大的鼓励;
什么是闭包?
闭包本质就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。
这句话是我在一篇文章中看到一位网友评论的闭包,我个人感觉非常言简意赅;
闭包怎么诞生的 🥚
其实严格来说,所有的JS函数都是闭包,都会产生闭包;但是因为多数函数的调用和函数的定义都在同一个作用域里面,所以这时闭包的存在与否无关紧要;
举个案例
let a = 11;
function fn() {
let a = 22;
function fn2() { return a;}
return fn2();
}
fn(); // => 22
其实产生一个闭包
非常简单,一个函数加上局部的作用域就能够产生闭包;
闭包有何优点与缺点 ?
优点:
- 闭包能够延伸变量的作用范围;
- 闭包可以避免全局变量的污染;
缺点:
- 因为闭包产生的变量都会常驻在内存中,对内存的消耗非常大,如果滥用闭包,会造成内存泄漏,降低网页的性能;
解决办法:
在退出函数之前,将一些不使用的局部变量全部删除,减轻内存的压力; - 在函数的内部再去创建一层函数,其实时不好的做法,因为闭包本身就会影响电脑的处理速度和内存消耗,如果不是非必须使用闭包,尽量减少使用闭包;
闭包能做什么?
1、获取正确的变量 🥩
相信大家都见过一道关于for循环与延迟器的题目,这题就很好展示了闭包如何获取正确的值; 未产生闭包:
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i); // => 5个 5
}, 500);
}
解决问题:
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i); // => 0 1 2 3 4
}, 500);
}
其实只要把全局变量替换成局部变量就会产生闭包;
2、外部能够读取内部里的变量 🥫
function f1() {
var n = 11;
function f2() {
return 11 + 11;
}
return f2;
}
var res = f1();
console.log(res()); // => 22
3、节流与防抖 💨
// 节流
function throttle() {
let flag = false;
return function () {
if(timer) return
flag = setTimeout(() => {
console.log(11);
flag = false
},500)
}
}
// 防抖
function debounce(){
let timer = false
return function(){
clearTimeout(timer)
timer = setTimeout(() => {
console.log(11);
},500)
}
}
4、自调用函数 🥝
自调用函数也会产生闭包fn函数;
var a = 11;
(function fn() {
console.log(a);
})()
总结
闭包我个人理解其实是为了保护函数内部的变量不受外部干扰,实现一些属性和方法的私有化,如果文章有不正确之处,欢迎大家指出,谢谢!