「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。
JS闭包可以说是一个很高频的面试题,而且非常的抽象,不容易理解,作为前端小白的我也时常搞不清楚,在查阅部分资料后谈谈个人对JS闭包的一个浅显的理解。
先讲讲作用域作用域又分为全局作用域和局部作用域
- 全局作用域
- 局部作用域 1.全局作用域定义的函数或者变量不会被销毁,全局作用域定义的变量在其他地方也能被使用
2.当变量在局部作用域声明,那这个变量就是这个作用域的局部变量,局部变量在使用后将会被垃圾回收机制回收。
<script>
let b = 1 //b在script标签下定义即为全局变量
function show(){
let a = 5
console.log(a)//5 //在函数show中定义,为show函数的局部变量
console.log(b)//1 //局部没有定义b,那么此时就会向上一层查找
} //如果第二层查找找不到,就会一直往上,直到找到全局变量
show()
console.log(a)//Uncaught ReferenceError: a is not defined
//由于a定义在函数show中,而全局中也找不到a,那么就会报错。
console.log(b)//1
</script>
换个简单的图助于理解,在全局作用域中访问变量a,明显是得不到,因为a是show的私有变量。而在函数show开辟的作用域中首先找不到b就会向他的父级查找,找到变量b。
个人浅显理解,作用域==作用范围。即在该作用范围内,我都能辐射,影响到你,能够被使用到,举个栗子。理解了作用域的概念那么接下来看看JS的闭包。
切入正题JS闭包
-
概念:指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。通俗一点,用个人的理解就是一个函数中返回了另一个函数,那么就形成了闭包。
-
优缺点:
优点: 1.延长变量声明周期 2.避免全局变量的污染,保证私有变量
在这里提一句,vue中常问为什么data是一个return返回的函数。其实这里也用到了闭包,保证了私有变量,使得各个组件之间的数据都是单独的,不会互相污染。
缺点:
1.常驻内存 会增大内存的使用量 使用不当会造成内存泄露
2.由于闭包涉及跨域访问,所以会导致性能损失
利用图解和代码来看一看闭包。
function show(){
let a = 1
function show2(){
console.log(++a)
}
show2()
}
show()//2
show()//2
显然如果你想让a变量持续增加是不太行的,因为每次执行一遍show函数都会开辟一块新的内存空间来存储show函数,也就是开辟一块新的函数作用域。那么就可以通过闭包来实现累加。
function show(){
let a = 1
return function show2(){
console.log(++a)
}
}
let hd = show()
hd()//2
hd()//3
let hq = show()
hq()//2
show方法返回一个函数用变量hd接收,接着hd()执行返回的这个函数show2,而show2用到了show函数中的变量a,因为show2还在使用着,垃圾回收机制也就会受不了,同样的show,a和show2是一起的都不会被回收就会一直存在。那么a的值也就会改变。至于为什么hd和hq会不同,因为再用变量接收的时候,也是开辟的两块空间进行接收。这个也和vue中的data很类似,不同的data函数之间不会相互污染。
感谢读者大大的阅读,作为一个前端小白,写作的内容多少会有点瑕疵,如果写的文章有不好值得纠正的地方,欢迎各位读者大大们的指正和探讨。