闭包是什么,如何使用?

这里是修真院前端小课堂,每篇分享文从

【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

八个方面深度解析前端知识/技能,本篇分享的是:

【闭包是什么,如何使用?】

 

1.背景介绍

是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。简单来说,假设函数A在函数B中进行了定义,并且当A在执行时访问了B内部的变量对象,那么B就是一个闭包

2.知识剖析

那么闭包的具体定义是什么呢?当函数可以记住并访问所在的作用域(全局作用域除外)时,就产生了闭包,即使函数是在当前作用域外执行。

这里有几个知识点需要先搞清楚

(1)变量作用域

变量的作用域无非就是两种:全局变量和局部变量。Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。而函数外部不能访问函数内部的局部作用域。这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上声明了一个全局变量

(2)生命周期

函数内部声明的局部变量会随函数的结束而被销毁,即 触发垃圾回收机制

(3)作用域链

作用域链是由当前环境和上层环境的一系变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问

我的理解是,但定义在一个函数中的另一个函数被return时就形成了闭包,闭包就是将函数内部和外部连接在一起的一座桥梁。

3.常见问题

以下代码为什么会造成内存泄露?

window.onload = function(){

var el = document.getElementById("id");

el.onclick = function(){

alert(el.id);

}

4.解决方案

内存泄漏的原因:执行这段代码的时候,将匿名函数对象赋值给el的onclick属性;然后匿名函数内部又引用了el对象,存在循环引用,所以不能被垃圾回收机制回收;

修改后的代码:

window.onload = function(){

var el = document.getElementById("id");

var id = el.id; //解除循环引用

el.onclick = function(){

alert(id);

}

el = null; // 将闭包引用的外部函数中活动对象清除

}

5.编码实战

点击按钮会弹出相应的数字0、1、2、3、4

function init({

var pAry = document.getElementsByTagName("button");

for( var i=0; i< pAry.length; i++ ) {

(function(arg){

pAry[i].onclick = function() {

alert(arg);

};

})(i);//调用时参数

}

}

思路:加一层闭包,i以局部变量形式传递给内存函数,在js任务4中的杀人游戏选中的身份死亡有用到。

6.拓展思考

在闭包中的this指向问题

7.参考文献

阮一峰的网络日志:学习Javascript闭包

详细图解作用域链与闭包

你可能感兴趣的:(闭包是什么,如何使用?)