1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>Document</title>
7 </head>
8 <body>
9 <script>
10 // 1.闭包无处不再,需要你去识别它。基于作用域书写代码时产生的自然结果,我们不需要为了利用它而刻意的去创建一个闭包
11 // 2.闭包是一种方式,他是一个能够引用其内部作用域变量的表达式
12 // 3.以下这个案例就是一个闭包,因为匿名函数(say)是在另外一个函数中声明的,在js中如果另一个函数使用了funtion关键字,则创建了闭包
13 // 4.在js中 如果在一个函数A中声明了另外一个函数B(出现了闭包),那么你调用了A函数以后,A里边的局部变量依然是可以被访问的
14 /* function sayHello(name) {
15 var text = name; // 局部变量text
16 var say = function () {
17 console.log(text);
18 };
19 return say;
20 }
21
22 var say2 = sayHello("lily");
23
24 say2(); //lily */
25
26 //
27 /* function say667() {
28 // 局部变量num最后会保存在闭包中
29 var num = 42;
30 var say = function () {
31 console.log(num);
32 };
33 num++;
34 return say;
35 }
36 var sayNumber = say667();
37 //通常一个函数执行完成以后,整个内部的作用域都会被销毁,因为引擎有垃圾回收机制来释放不在使用的空间
38 //而闭包的神奇之处就是 可以阻止这个事情的发生,内部作用域依然存在,因为sayNumber还在使用这个作用域
39 sayNumber(); // 输出 43 */
40
41 //
42 /* var a, b, c;
43 function fn1() {
44 // 局部变量num最后会保存在闭包中
45 var num = 42;
46 // 将一些对于函数的引用存储为全局变量
47 a = function () {
48 console.log(num);
49 };
50 b = function () {
51 num++;
52 };
53 c = function (x) {
54 num = x;
55 };
56 }
57 fn1();
58 b();
59 a(); // 43
60 c(5);
61 a(); // 5
62 var oldLog = a;
63 //在上边的案例中,当我们再次调用fn1时候,一个新的闭包就被创建了,旧闭包的变量 a b c被新闭包的函数覆盖
64 // 每次调用fn1 都会创建一个新的闭包
65 fn1();
66 a(); // 42
67 oldLog(); // 5 */
68
69 //
70 function buildList(list) {
71 var result = [];
72 for (var i = 0; i < list.length; i++) { //for循环已经执行完了,此时i为3,
73 var item = "item" + i;
74 result.push(function () {
75 console.log(item + " " + list[i]);
76 });
77 }
78 return result;
79 }
80 function testList() {
81 var fnlist = buildList([1, 2, 3]);
82
83 for (var j = 0; j < fnlist.length; j++) {
84 fnlist[j](); //打印3次 ‘item2 undefined’
85 }
86 }
87 testList();
88 </script>
89 </body>
90 </html>