前言
这篇文章是我读了,阮一峰老师关于闭包的一篇博客的读后感,为了加深自己对闭包的理解,在这里写下自己对闭包的理解,欢迎大家指出错误。
一、变量的作用域
要理解闭包,首先说一下Javascript特殊的变量作用域。
变量的作用域有两种:局部变量和全局变量。
Javascript的函数内部可以读取全局变量,而外部函数不可以却不可以读取某个函数的局部变量。
二、如何从外部读取局部变量?
这里我直接引用了阮一峰老师的例子。
我们看一段代码:
function f1(){
n = 100;
function f2(){
alert(n);
}
}
在这段代码中f1的局部变量对于f2来说都是可见的,但反过来就不行了。这是JS的“链式作用域”。
“链式作用域”是指:子对象会一级一级地向上寻找所有父对象的变量,所以,父对象的所有变量对子对象可见。
如果把function f2用return返回会怎么样?
function f1(){
n = 100;
function f2(){
}
return f2;
}
这样外部函数就可以,通过调用f1来获取f1的局部变量了。
三、什么是闭包?
在阮一峰老师的博客中,他提到闭包可以理解为:“定义在一个函数内部的函数”。
在这里我理解闭包为,有权访问另一个函数作用域中变量的函数,通常这个函数在被访问变量函数的内部。
四、闭包的用途
闭包的作用一是读取函数内部的变量(内部函数也可以赋值给变量),二是需要变量一直保存在内存中但又不会“污染”全局的变量。
看一段代码:
function A(){
var count = 0;
function B(){
count ++;
console.log(count);
}
return B;}var c = A();
c();// 1
c();// 2
c();// 3
B在A中,因此B依赖于A,c引用了B,所以A间接被c引用,且A不会被回收,一直保存在内存中。count是A中的一个变量,它的值在B中被改变,函数B每执行一次,count的值就在原来的基础上累加1。因此,A中的count一直保存在内存中。
五、闭包的使用方法
1、返回函数的方式:(这里是一个匿名函数)
function A(){
var count = 0;
return function (){
count ++;
console.log(count);
}
}
var c = A();
c();// 1
c();// 2
c();// 3
2、返回函数表达式
var A = function(){
var count = 0;
var B = function (){
count++;
console.log(count);
}
return B;
}
var c = new A();
c();// 1
c();// 2
c();// 3
3、也可以以数组的形式返回
var A = function(){
var count = 0;
function B(){
count++;
console.log(count);
}
return {
b :B;
};
}
A.b(); //1
A.b(); //2
A.b(); //3