参照文章:(https://www.cnblogs.com/JIANGCHEN520/p/7118656.html)
闭包的定义:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的变量,且返回的这个函数在外部被执行,就产生了闭包.
闭包是基于正常的垃圾回收处理机制下的。一般情况下,一个函数执行完毕,里面声明的变量会全部释放,被垃圾回收装置回收。但是闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存,不会被垃圾回收装置回收。
本质上,闭包是将函数内部和函数外部链接起来的桥梁。
我们来看一个例子:
function test(){
var arr=[];
for(var i=0;i<10;i++){
arr[i]=function(){
document.write(i+" ");
}
}
return arr;
}
var myArr =test();
for(var j=0;j<10;j++){
myArr[j]();
}
看完这个代码,在不了解闭包之前,我们认为打印出来的结果为0,1,2,3,4,5,6,7,8,9。但是真实打印出来的结果为十个10。这是为什么呢?
我们来分析一下这段代码,在test中,声明一个数组arr,和一个变量i,函数返回数组arr,而这个数组arr中包含了10个打印出变量i的函数。而闭包是怎么出现的呢?让我们继续看执行过程。首先执行var myArr=test();那么函数test()就执行了,但是执行完毕之后,变量i就被释放回收了吗?让我们想一想,如果i被释放回收,那么数组中的函数在外部执行时(注意,在函数被存入数组时,并没有被执行),i是从哪儿来的?很明显,i不可能凭空产生,所以这里的i只能是test中的变量i,它并没有被释放回收。这个时候arr中的所有函数就都是闭包。
既然形成了闭包,那我们在访问test中产生的变量的时候,访问的都是相同的变量。所以当数组中的函数在外部访问变量i的时候,访问的都是同一个i。数组访问变量的时期在第二个for循环的内容执行的时候,而这个时候,test已经被执行完毕,test中的i的值已经变成了10。所以最后会在页面上打印出 来十个10。