从 blog.csdn.net/ef_ef/artic… 迁移的文章,傻逼csdn把我号封了
好像我的理解有点问题,但是这篇文章写了这么多了,就不舍得删掉了,就这样吧。
前言
这篇文章有些东西都是我自己的猜测,百度也百度不到,也可能是我不太会百度...希望有懂的人能反驳一下。 但是我觉得这篇文章用来学习闭包还是挺不错的,至少很浅显易懂。
总结
- 闭包是编程语言的特性(编程语言中函数的特性),有些编程语言是支持闭包的,比如js的函数就是闭包的,有些语言不是闭包的,额我也不知道有哪些...
- 函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包;相反,函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包
- 闭包和不闭包对编程语言的影响主要在于: 要不要把函数的形参或变量当成垃圾进行垃圾回收
闭包是个什么鬼
首先再强调一下,js是闭包的。 转化成函数就是下面这样:
let innerFun;
let a = 1;
function outterFun() {
let a = 2;
innerFun = function() { // (*)
console.log(a);
}
}
outterFun();
innerFun();
控制台打印的是2而不是1,至于原因是什么,你可以这么理解:innerFun这个函数声明在(*)行,所以这个a要从(*)行所在的外部作用域往外找,这个作用域里面刚好有a,且a=2,就不用继续往外查找了,它不可能找到第二行的a=1,所以控制台打印的就是2。
我上面说的,a是从innerFun函数声明的位置往外找的,注意:这里的重点是函数声明的位置!!! 这就是闭包的重点------函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包。
不闭包又是什么鬼
那有闭包,肯定就有不闭包,不闭包又是怎么样的呢,我就有下面这样的猜测:
let innerFun;
let a = 1;
function outterFun() {
let a = 2;
innerFun = function() {
console.log(a);
}
}
outterFun();
innerFun(); // (*)
还是同样的代码,假设js是不闭包的语言,那这个a就应该是从函数执行的位置开始往外查找的吧(只是猜测),函数执行的位置在(*)行,那么往外查找到的第一个a就是在第二行,所以a=1,控制台就应该输出1。
函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包。
闭包与不闭包的区别: 垃圾回收
闭包是从函数声明处查找变量的,而且我们知道,只要变量还有机会被使用到就不会被垃圾回收,那么外部函数outterFun即使执行完,内部变量a依旧能被使用,所以a就不会被当做垃圾被回收。
相反,不闭包的话,a就会被垃圾回收。
总结
- 闭包是编程语言的特性(编程语言中函数的特性),有些编程语言是支持闭包的,比如js的函数就是闭包的,有些语言不是闭包的,额我也不知道有哪些...
- 函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包;相反,函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包
- 闭包和不闭包对编程语言的影响主要在于: 要不要把函数的形参或变量当成垃圾进行垃圾回收