闭包与立即执行函数

闭包

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
这里注意,内存泄漏并不是真正的泄露,而是指过多的占有资源导致可使用的资源变少

闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。
例如

function test1() {
	var arr = [];
	for (var i = 0; i < 10; i++){
		arr[i] = function () {
			document.write(i + " ");
		}
	}
	return arr;
}
var myarr = test1();
for (var j = 0; j < 10; j++) {
	myarr[j]();
}
//运行结果 10 10 10 10 10 10 10 10 10 10 

为什么会出现这种情况?思考原因

原因其实就是在于在函数嵌套的过程中,内部函数被扔到了外面,生成了闭包,在函数真正执行时使用的i变量仍为test1函数中的变量,执行时i变量已执行完for循环变为10。

如何解决这种问题?就要使用到立即执行函数

立即执行函数

函数形式:小括号中 函数声明+执行符号

var num = (function (<参数>) {
    var d = 0;
	//函数体
    return d;
}(参数值))

函数原理:
在JavaScript中有这样的语法规定:
只有表达式才能被执行符号执行,能被执行符号执行的函数,名字会被自动忽略

所以当函数声明被转换成表达式时就可以被执行并且忽略了名字
通过加号+ 非!等数学符号都可以将函数声明转化为表达式,当表达式被执行后,自动销毁。它的作用是针对初始化功能的函数

在上述程序中,立即执行函数是唯一的解
要想保存创建时的变量数据,可以通过闭包

function test2() {
	var arr = [];
	for (var i = 0; i < 10; i++){
		(function (j){
				arr[j] = function () {
					document.write(j + " ");
				}	
		}(i))
	}
	return arr;
}
var myarr = test1();
for (var j = 0; j < 10; j++) {
	myarr[j]();
}

分析test2程序创建出的函数的作用域链

执行函数时执行document.write(j + " ")语句,
使用到的j为定义函数时立即执行函数传进来的j,因为生成闭包所以j被保存
当函数执行时,[[scope]]的为 0->函数自己的AO(关于AO见上一篇博客)
1->立即执行函数的AO
2->test1的AO
3->GO
因为for循环并不产生作用域,所以for循环中的j变量并不对函数造成影响。
所以在函数执行时,变量j取的是立即执行函数的AO中的j变量

前端小白,欢迎批评指正~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值