JS进阶:谈谈对闭包的理解

时间:2021-09-02 03:30:59

前言

这篇文章是我读了,阮一峰老师关于闭包的一篇博客的读后感,为了加深自己对闭包的理解,在这里写下自己对闭包的理解,欢迎大家指出错误。

一、变量的作用域

要理解闭包,首先说一下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