【前端进阶】浏览器的垃圾回收机制及JS中的闭包

浏览器的垃圾回收机制(内存释放机制)

栈内存释放

  1. 加载页面时,浏览器会形成一个全局上下文,只有页面关闭后,全局上下文才会被释放
  2. 函数执行时,会形成一个私有上下文进栈执行, 当函数中代码执行完毕,大部分情况下,私有上下文会出栈释放,以此优化栈内存

堆内存释放

  1. 查找引用(谷歌):浏览器在空闲时或指定时间内,查看所有堆内存,把没有被占用的堆内存释放
  2. 引用计数(IE):创建了堆内存,被占用时浏览器计数+1,取消占用时浏览器计数-1,当计数为0时,把堆内存释放;某些情况下会导致计数混乱,出现内存泄漏的情况

闭包

原理

函数运行的一种机制

  1. 函数执行会生成一个是私有上下文
  2. 里面的私有变量,受到了私有上下文的“保护”,不受外界干扰
  3. 当函数内部值被其外部占用时,形成不被释放的私有上下文,里面的私有变量和一些值就会被“保存”起来,这些值可被其“下级”上下文调取使用
  4. 我们把函数的这种“保护”/“保存”机制称为“闭包”
  5. 弊端:如果大量使用闭包,会导致栈内存太大,页面渲染变慢,性能受到影响;某些代码会导致内存泄漏(例如死递归),因此要合理使用闭包
// fn内部函数f被外部变量f占用,导致fn执行完毕无法出栈释放,形成闭包
function fn(){
   
	let x = 10;
	return function f(){
   
		console.log('闭包')
		console.log(x)
	}
}
let f = fn();
f()

// 死递归 Uncaught RangeError: Maximum call stack size exceeded(内存泄漏)
function die(x){
   
	die(x+1)
}
die()

闭包的应用场景

循环事件绑定(var)

// 由于i为全局变量,所以循环时i的值已变更,当点击button时,打印出的值位i最终的值
var btns = document.querySelectorAll('button')
for(var i = 0;i < btns.length; i++){
   
	btns[i].onClick = function(){
   
		console.log(i) // btns.length
	}
}

// 解决方案1:基于闭包机制
var btns = document.querySelectorAll('button')
for (var i = 0; i < btns.length; i++) {
   
	// 每一轮循环都会形成一个闭包,存储私有变量i的值
    (function(i){
   
        btns[i].onclick = function(){
   
            console.log(i)
        }
    })(i)
}
// 或者
for (var i = 0;i < btns.length; i++) {
   
	// 每一轮循环都会形成一个闭包,存储私有变量i的值
	btns[i].onclick = (function(i){
   
        return function(){
   
            console.log(i)
        }
    })
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值