闭包——十万个为什么
什么是闭包?
简单的来说闭包就是函数。那函数是不是闭包呢?
网上有一句话js函数皆是闭包。我觉得这句话是不太准确。我们先这直接忽略这个说法
先来看下 相对官方说法:闭包是指有权访问另一个函数作用域中的变量的函数
看到这据话有点懵,所以我们拆解下变成 ————闭包是指有权访问另一个(函数作用域中的)变量的函数
在换成我的理解:闭包就是函数嵌套函数,里面的函数引用外面函数的变量。
什么是函数嵌套函数?
举个粟子1
function fun1(){
function fun2(){
{
}
什么是里面的函数引用外面函数的变量。
举个粟子2
function fun1(){
var n=10;
function fun2(){
console.log(n);//这里的n没声明,使用的是上级作用域fun1的n
}
}
{友情提示基础比较好的可以直接跳到下面看 闭包的超级简单粟子}
闭包有什么特性?
闭包有三个特性
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收
函数嵌套函数这个在粟子1中已经说了
函数内部可以引用外部的参数和变量在粟子2也说了
参数和变量不会被垃圾回收机制回收这个又是什么意思呢?
闭包不也是函数吗?这么可能不会被回收呢?而且不是说
局部变量会在函数完成时被删除吗?
我们先带着这个疑问,做几道题
带着 在函数开始时会创建局部变量,在函数完成时会删除它们 这个问题看下面代码。
也就是说函数没调用前只是声明跟定义,并木有被创建,等到调用了才创建(换句话说如果没被调用就相当于function fun(){},调用才创建里面的代码)
有人问为什么代码被销毁了第二个fun1();还可以调用?那是因为函数在调用时候才往里面加代码
如果还不理解,那就换个比喻,假如有一个盒子1,放在上面,没调用之前,我放着,调用时,我拿东西装进去,调用完,我就扔掉这个盒子1里面的东西;然后在第二次调用之前,我用盒子1在把里面的东西装进去,调用时,我继续放东西进去,调用后我继续扔掉盒子东西。
我们在看下面代码
为什么第二个fun1();控制台输出的是12?
这里有一个陷阱,a++ 没有在局部变量声明所以用的是全局变量的a所以会改变全局变量 var a = 10的值 变成var a = 11 ;(全局变量会在您关闭页面是被删除。)
还要肯定一件事就是第一个fun1()调用后完成后就销毁。
调用第二个fun1()时;全局变量的var a = 11;所以控制台输出是12;
了解了上面两个代码后我们在看一下
闭包的超级简单粟子
从这个粟子中我们可以fun1();也是会销毁的,不过是要等到内部函数结束后才销毁,所以利用这个特点就产生了闭包这种说法。
在回顾下 参数和变量不会被垃圾回收机制回收这句话
这句话我觉得也有点毛病 应该说这是一个相对于谁的问题,是暂时不会被回收。
最后在说下 闭包的目的和优缺点
目的:使用闭包主要是为了设计私有的方法和变量。
闭包的优点是可以避免全局变量的污染,
缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏。
在在在最后,在顺便了解下JavaScript垃圾回收的机制(了解懂吧,就了解就行啦)
JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存
什么叫不再使用的变量?
不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量,直至函数结束(闭包中由于内部函数的原因,外部函数并不能算是结束)
结尾什么是闭包
闭包是指:有权访问另一个 函数作用域中的 变量的函数
上面这话如何理解--------我的理解:闭包就是函数嵌套函数,里面的函数引用外面函数的变量。