在网上查看过一部分文档之后,才弱弱的打开博客,准备记录一下最近重新对闭包的认识。
对于刚接触Javascript的同学们来说,闭包可以算是一个比较难理解的知识点了。因为刚开始对JS这门语言还是不是很熟悉,所以理解起来肯定是有一定难度的,而后来又因为接触到了很多新的东西,可能就对闭包这个知识点淡忘了,存留者的可能就是当初最开始接触闭包时候的印象吧。在网上翻看了一部分同学关于闭包的博客后,很明显的一个感觉是,似乎每个人对闭包的理解都有一定的差异,于是乎我用了一天的时间来研究这个问题----->什么是闭包呢?(当然,这也仅仅是我个人的理解)
闭包:内部函数被保存到了外部,这种情况一定会生成闭包。内部函数一定会保存外部父级函数的一个作用域,当内部函数的引用被保存在外部时,它的父级函数执行完后执行器上下文被销毁,,但是这个时候因为内部函数的引用上是保存着外部函数的执行期上下文的内容的。在被定义的时候,内部函数和外部函数的执行器上下文其实就是同一个东西,但是,在内部函数执行的时候,又会在外部函数执行期上下文的基础上形成自己新的AO,并且存储在里边。
例如:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="">
function test() {
var num = 0;
function add(){
console.log( ++ num);
}
return add;
}
var myAdd = test();
for(var j = 0; j<10; j ++){
myAdd();
}
</script>
</body>
</html>
这个就是一个闭包的例子,add函数被执行在它的上一级的test函数的外边(test返回了add这个函数)。按理来说,test函数在执行结束后就会被立即释放,那么它里边的add函数也同样会被释放掉。可是结果:
也就是说,在add这个函数被保存在外部之后,它的作用域在test函数执行结束后还是仍然保存着的,而且还可以被调用和使用。
那么这个内部是一个什么样的机制呢?
首先我们得知道,其实函数也是一中对象(Obj),既然是对象,那么就一定有他的方法,[[scope]],就是一种。只不过这个方法是提供给浏览器引擎使用的,我们是无法调用的。而这个[[scope]]里边存储的就是我们常说的作用域链,这个作用域链指向该[[scope]]对应函数的执行期上下文。在一个函数执行结束后,它实际上释放的是自己[[scope]]里边自己因为执行所产生的作用域链,而自己实际产生的AO(执行期上下文)还是存在着的,然而,这时候,因为自己里边的嵌套函数虽然在外部函数执行的时候虽然没有被执行,但是它(里边的嵌套函数)在被定义的时候就在外部函数的AO(执行期上下文)的基础上形成了自己的AO(执行期上下文),在外部函数的作用域链被销毁的时候,内部嵌套函数的AO和作用域链确实完好无损的。所以在内部齐奥淘函数被保存在外部时,还是可以被调用的。这种现象就被称为闭包。。。。
再画图说明一下:
emmmm....就是这么个意思。。
最后再说一说我对函数的理解吧:
函数就好比一个一个的小房间,是一个单独的空间,而这个域(作用域)也只有函数才有的一个(我觉得可以称作属性吧)。
所以闭包就是一个大房间里边有一个小房间,但是在这个大房间已经被拆掉之后,小房间里的一些东西还是可以使用的。。。