mdn对闭包的定义:闭包是函数和声明该函数的词法环境的组合。
可能读了上面的定义你有点懵,但是没有关系,我们继续往下看。
其实对闭包的定义我们可以分为从理论角度或者从实践角度来看。
从理论角度来看:
所有的函数都是。因为它们都在创建的时候就将上层上下文的数据保存了起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用的是最外层的作用域。
当然我们不能从理论角度来定义闭包,我们需要从实践角度来定义闭包,下面是从实践角度来定义的闭包。
从实践角度来看:
需要满足下面两点的才是闭包:
注意:在定义函数的时候,函数的作用域就已经定义好了。
1 | (function(){ |
下面我们再来看一个经典的例子,可能大家才开始学习的时候,都遇到过类似的问题。
首先,我先将问题列出来,大家先看一看:
1 | var data = []; |
此时你会发现和你想象中打印的不太一样,其原因就是因为作用域的问题,在for循环中,用var定义的变量是一个全局变量,最终循环结束,i保存在内存中不会马上销毁,所以当你在循环完的时候看到的i是3。当执行data[0]、data[1]、data[2]函数的时候,使用的是i为3。
如果你想实现打印出0,1,2效果的话,解决办法就是闭包。
1 | var data = []; |
大家先试着消化消化闭包,可能对初学者还有点懵,但是没关系,在你的代码生涯中还会出现许多许多的闭包问题,当你多遇到多思考就会真正的理解它了。
在后面我会写关于执行期上下文的笔记,此时我会再将闭包用执行期上下文来给大家展示,此时你就会真正意义上的理解闭包发生的过程了。