JavaScript中什么是闭包?

在开始之前我得先吐槽一下: 到底是哪个扑街发明的这个词?

在我没有了解闭包是个啥玩意儿时,闭包是啥玩意儿,以前怎么没听过,听起来很厉害的样子

其实你生活中写的很多代码都是闭包,在你开始学 js 的时候就已经用过闭包了

闭包: 简单来说,闭包是指可以访问另一个函数作用域中变量的函数

COPY
1
2
3
4
5
6
7
var age = "18";

function fun() {
console.log(age);
}

fun(); // '18'

以上代码就是闭包了,简单吧?
在你写的很多代码里,肯定有这种写法

你会说:这… 就这么简单?可我在网上看到的描述不是这样的啊,都是要return的呀!

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 第一种写法
function fun1() {
var age = "18";
function fun2() {
console.log(age);
}
return fun2;
}
var fun = fun1();
fun(); // '18'

// 第二种写法
function fun1() {
var age = "18";
var fun2 = function () {
console.log(age);
};
return fun2;
}
var fun = fun1();
fun(); // '18'

// 第三种写法
function fun1() {
var age = "18";
return function fun2() {
console.log(age);
};
}
var fun = fun1();
fun(); // '18'

接下来我们看看与一开始说的闭包代码

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var age = "18";

function fun() {
console.log(age);
}

fun(); // '18'

// ----------------------------------

// 第一种写法
function fun1() {
var age = "18";
function fun2() {
console.log(age);
}
return fun2;
}
var fun = fun1();
fun(); // '18'

把 fun1 函数和 return 去掉不就是可上面的一样了吗
对,这就是闭包,那为什么有些人说要包一层,然后 return 出来呢?

答:如果不这样做的话,就达不到闭包的标准了,也就是相当于一个全局变量,如果你每个都这样写的话,就会照成全局变量名污染。
所以要套一个函数,达到局部变量的效果,最后 return 出来就可以了

简而言之: 如果你写很多的变量,全是全局变量会照成全局变量污染,如果是团队写在开发,你写几个全局变量,我写几个全局变量,最后在下班之前 push 一下代码,如果你两写的变量名相同冲突了,而这个变量又关系到你一天的成果,这必然要有一个人要重写(修改)。

那么如何解决呢?

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var zhangsan = function () {
var age = "21";
function getAge() {
console.log(age);
}

// ...... 其他更多更复杂的代码逻辑

return { age: age, fun: getAge };
};

var lisi = function () {
var a = "xxxx";
function abc() {
console.log(a);
}

// ...... 其他更多更复杂的代码逻辑

return { temp: a, fun: abc };
};

var zhang = zhangsan();
var li = lisi();

zhang.age; // "21"

li.temp; // "xxxx"

看看,这就不会起冲突了(这就类似于模块化开发一样,我想要让你访问的数据,我把它暴露出来 export 不就是和 return 差不多吗)

最后呢,给大家看一个小小的段子吧 摘抄至:Tiger 的解答

我的年龄是秘密,你想知道。
但是每次我都含糊其辞的对你说 undefined;
为了防止我自己也忘记或搞错自己的年龄,我办了一张身份证,上面记录我的年龄信息,藏在我家里。
你知道了这件事,为了得到我的年龄,决定对我投其所好,于是你送我一只逗比间谍猫。
作为感谢我给了你一把我家的钥匙,方便你有空来看猫。这只猫实在太神奇了,每次都能找到我的身份证,并把信息传递给你。
于是你每次想知道我的年龄的时候就来看猫,然后间谍猫每次都能把我的最新的年龄信息反馈给你。

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

var day = 0;
var timer = setInterval("dayChanges()", 24 * 60 * 60 * 1000); //定时器

//每过24小时 次函数运行一次,我的年龄又多了一天
function dayChanges() {
day++;
}


// 下面的代码就是一个比较常见的闭包。

//我家
function isMyHome() {
var myAge = 0; //我的身份证信息
if (day % 365 == 0) {
//我的年龄变化
myAge += 1;
}

// 我家钥匙
function myHomeKey() {

return myAge; //return 就是间谍猫
}
return myHomeKey; //给你我家的钥匙。
}
var key = isMyHome(); //你拿到我家钥匙
var you = key(); //得到年龄。

console.log(you)
Authorship: Lete乐特
Article Link: https://blog.imlete.cn/article/JavaScript-Closure.html
Copyright: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite Lete乐特 's Blog !