闭包:
在我们JavaScript中除了基本的数据类型来保存以及操作数据,还会用到一个比较特殊且歧义相对较大的东西,即,闭包。那么我们很多学习前端的小伙伴在初次学习闭包的时候都会由很多疑问,如:闭包到底干嘛用的?闭包产生的条件是什么?既然闭包会导致内存泄漏呐为啥还要用闭包?直接用基本数据或者对象不久完事儿了...等一系列灵魂拷问,那么本次就来浅谈一下闭包该如何处理,希望能帮助进击前端的伙伴们有所启发。
那么在进行闭包的前面我想和朋友们讨论一下大家一直关心的问题,即内存泄漏和溢出的问题了,那我们都知道到内存的溢出由于目前具有剩余的内存小于程序执行所开辟需要的内存,导致内存溢出,那什么情况会发生这样的问题呢,其中闭包的数据不销毁长时间占据内存导致后面的对象变量函数等需要开辟新空间而不够引发内存泄漏导致溢出。既然问题的所有矛头都指向这万恶的闭包,那我们为什么又要使用闭包,闭包这个概念又为什么如此重要呢?
其实 我们不妨将问题的方向转向内存泄漏和溢出,那么内存泄漏是如何定义的呢?我们应当认为不必要的数据等垃圾对象长时间占用内存导致泄漏及溢出,那什么时候会用到闭包?那一定是重要的数据,如私有数据只提供访问接口不提供写入操作或者暴露隐式操作函数,这类数据一定是重要的。好比我们游戏中背包的数据,我有十个很稀有的东西如果能被别人看到那他召集人手把你刀了掉落装备那岂不是很危险,甚至在公司开发中有的数据必定只提供访问接口,那这些数据能被别人随意修改是相当危险的操作,所以我们不应该从闭包的弊端(内存泄漏)来否定闭包,应当从闭包能带来的开发思路及角度来优化闭包。眼神犀利的朋友应该以及发现了我们以及从定义否定了闭包带来的数据泄漏,因为闭包所需要操作的数据必定是重要的。
那么其实闭包所带来的开发思路类似于后端的私有类私有属性,学过后端Java开发的朋友应该都有所了解,Java在村此一个私有类的时候只向外暴露访问接口方法,不会让用户擅自修改其内容,而闭包的存在与此有异曲同工之妙,这也让JS这个弱类型语言又增添了一些浪漫的色彩,所以在学习闭包的时候朋友可以多一些宽容,编程的思路也是我们学习语言的重要内容。
那聊了这么多,想必也清除了朋友们心中对闭包的障碍,那么我们是时候回归正题开始研究闭包了。首先得从闭包的定义说起,满足闭包的条件那必然是嵌套内部的函数引用了外部父函数的变量(函数)时就产生了闭包。但这里必须要说的是一定要调用父函数才能生成闭包,闭包的区域在子函数的作用域中,不一定满足调用子函数,调用父函数必须满足。
那么有些朋友看不到具体内容我们来上一段简单的代码方便理解闭包定义:
function fn1(){
var a = 1;
var b= '123'
function() fn2{ // 执行函数定义的时候就会产生闭包
console.log(a);
}
}
fn1();
此处就是一个简单的闭包产生,在内嵌函数fn2中使用父函数fn1的属性a,需要注意的是必须在外部执行函数fn1() 才会产生闭包,闭包区域就在fn2所包含的作用域。但是细心的朋友会看到在fn1中并没有调用fn2啊?这样还能产生闭包吗?