1、什么是闭包
-
函数里面包含的子函数,子函数访问父函数的局部变量
-
通过return将子函数暴露在全局作用域,子函数就形成闭包
-
通过闭包,父函数的局部变量没有被销毁,可以通过闭包去调用,这个局部变量也不会被全局变量污染
执行上面的代码可以看到打印出123,在函数testFunc里面可以访问变量testVar,这个全局作用域就是一个闭包。其实我们在实际工作中经常会写这样的代码,只是对闭包界定不是很清楚,具体问起来也不知道怎么来解释闭包
<script>
var outerValue = '我是外部变量';
var later;
function outerFunction(){
var innerValue = '我是内部变量';
var innerFunction = function(){
console.log(outerValue);
console.log(innerValue);
};
later = innerFunction;
}
outerFunction();
later();
</script>
我是外部变量
我是内部变量
可能大家觉得外部函数outerFunction执行结束后,内部变量innerValue就消失了,但是实际上都打印出来了,这就是闭包的作用。在外部函数执行结束后,将内部函数innerFunction的引用复制给later,执行later相当于执行内部函数,但是仍然可以访问innerValue。
闭包的核心原则是:
- 内部函数的参数是包含在闭包中的
- 作用域外的所有变量,即便是函数声明之后的那些声明,也都包含在闭包中
- 在相同的作用域中,尚未声明的变量不能提前引用即变量提升
闭包的优点:
1、避免全局变量的污染,同时局部变量没有被销毁,驻留在内存中,还可以被访问
2、规避冲突。像jQuery等第三方库都会妥善的将内部私有的函数和变量隐藏起来,防止在使用过程中如果有意或者无意使用的相同的变量名或者函数名引发冲突
闭包缺点:
1、使用不当,会造成内存泄露
2、将函数片段用函数包含起来,首先会起一个函数名,这个函数名本身也就污染了所在的作用域;其次必须通过函数名调用才能运行其中的代码。解决方案是:立即执行函数,用表达式将函数片段包起来,然后立即执行。这个函数名在所在作用域中不能被调用,它只是被绑定在函数表达式自身的函数中