今天突然发现自己忘记闭包知识点了,复习一下!!!
注:这篇博文只是回顾知识,若看详解闭包请翻看以往博文
先回顾一下闭包基础知识
何为闭包?
简单点说在A函数里面创建一个函数B,则B就是闭包
闭包的作用:
1. js作用域,函数内部可以调用函数外部的变量,反之不行,如果需要,则可以使用闭包
var n = 999;
function f1() {
console.log(n);
}
f1()//999
上面例子中,函数f1()可以读取全局变量n。但是函数外部却无法读取到函数内部声明的变量。
var n = 999;
function f1() {
console.log(n);
var n1 = 888
}
console.log(n1)
f1()//999
运行结果如下:
函数外访问函数内变量直接显示n1未定义,报错。
那么我们有时候需要得到函数内部的变量,也就只能通过在函数内部在定义一个函数。
function f1() {
var n = 999;
function f2() {
console.log(n); // 999
}
}
上面代码中,函数f2就在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。
我们通过上面例子看出来了,f2可以读取f1的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量了。
function f1() {
var n = 999;
function f2() {
console.log(n);
}
return f2;
}
var result = f1();
result(); // 999
上面代码中,函数f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了。
闭包也就是函数f2,即能够读取其他函数内部变量的函数。由于在 JavaScript语言中,只有函数内部的子函数才能读取内部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包最大的特点,就是它可以“记住”诞生的环境,比如f2记住了它诞生的环境f1,所以从f2可以得到f1的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
2. 一般函数执行完后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象),但是闭包情况下,不会被摧毁,所以闭包,会占用更多的占用内存。
从实例中感受一下
var name = "The Window";
var object = {
name : "My Object",
a : function(){
return function(){
return this.name;
};
}
};
alert(object.a()());
如上输出
如上解析:
object.a()();
是一个立即执行函数,相当于:
object.a()() ==> function(){
return function(){
return this.name;
};
}()
结果返回return this.name;
this指向window也就是var定义的全局变量
var name = "The Window";
输出结果也就是The Window
下面给出一个例子看看闭包规范:
function outerFun(){
var a=0;
function innerFun(){
a++;
alert(a);
}
}
innerFun()
上面的代码是错误的.innerFun()的作用域在outerFun()内部,所在outerFun()外部调用它是错误的
改成如下,也就是闭包:
function outerFun()
{
var a=0;
function innerFun()
{
a++;
alert(a);
}
return innerFun; //注意这里
}
这样当它执行的时候又返回函数innerFun(){}就形成了一个闭包。
总:当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.