前言
JS中闭包是什么?
闭包有什么作用?
一、闭包是什么?
定义在函数内部的一个函数
也可以理解为:具有作用域的代码块就是闭包
作用:将函数内部和函数外部连接
二、闭包的特点
1. 一个函数返回函数内部的工具函数,外部通过工具函数间接访问函数局部变量的过程
案例:
function alipay() {
var money=500
//不能让函数之外的代码直接操作money 但是可以让自己的内部工具操作 然后返回这个工具
function tool () {
money-=20
}
return tool
}
function meituan () {
var aplitool=alipay()
aplitool()
}
meituan()
2. 利用了函数每次调用时生成的独立调用栈,每次调用内部的局部变量或者形参都是独立的 来保存一些临时数据
案例:写一个for循环,让它按顺序打印出当前循环次数
var arr=[]
for(var i=0;i<5;i++){
function fn(){
console.log(i)
}
arr[i]=fn
}
arr[0]()
arr[1]()
arr[2]()
arr[3]()
arr[4]()
//我们预期的是想数组每个下标都打印相应的下标数字,结果却都打印5
//这里因为js是单线程的缘故,所以是先执行了for循环,然后函数外部是无法改变函数内部的值,
//再外部再调用函数时就出现了调用后 函数里面的i就是最后执行完成后i再自加1的结果为5
//为了解决上面的问题,引入闭包来保存变量i,将for循环中的循环值i作为实参传递
var arr=[]
for(var i=0;i<5;i++){
(function(index){
arr[index]=function fn(){
console.log(index)
}
})(i)
}
arr[0]()
arr[1]()
arr[2]()
arr[3]()
arr[4]() //打印0,1,2,3,4
3. 利用函数的独立作用域来生成业务代码块 ,使内部的变量相互不冲突不会污染全局变量
三、闭包的缺点
虽然闭包好用 可以解决很多问题 但是没使用好的话就会有一些致命的问题:内存泄漏
浏览器的内存管理机制是:垃圾回收机制和引用计数 ==> 通过底层浏览器的代码实现的功能
也就是系统会定期查看我们的js执行情况,观察创建的对象有没有可能会被使用,如果没有可能 就释放内存,
每一个对象都有"人"引用它 如果引用的"人"数为0就释放内存
内存泄漏: 浏览器运行网页 就会执行js代码,引用数据会在内存中占用内存空间
如果有一个对象创建了 而且占用了内存 缺没有什么业务使用(想用都用不了) 这种情况就是内存泄漏
解决方法
1.尽量避开 不要使用闭包
2.在可能存在泄漏的地方把标识符引用为null
案例:
function fn() {
var obj = {
age: 22
}
function tool() {
return obj.age
}
return tool
}
var re = fn()
re=null;