1 /*
2 闭包
3 闭包就是能够读取其他函数内部变量的函数
4
5 函数作为返回值
6 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回
7 */
8 function lazy_sum (arr) {
9 var sum = function () {
10 return arr.reduce (function(x, y) {
11 return x + y
12 })
13 }
14 return sum
15 }
16 var f = lazy_sum([1, 2, 3, 4, 5])//function sum() 返回的并不是求和结果,而是求和函数
17 // f() //15 调用函数f时,才真正计算求和的结果
18
19 //在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
20
21 //请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数,调用结果互不影响
22
23
24 function count() {
25 var arr = []
26 for (var i=1; i<=3; i++) {
27 arr.push((function () {
28 return function (n) {
29 console.log(n * n)
30 }
31 })(i))
32 console.log(i)
33 }
34 return arr
35 }
36
37 var results = count()
38 var f1 = results[0]
39 var f2 = results[1]
40 var f3 = results[2]
41 f1()
42 f2()
43 f3()
44
45
46 function f4(){
47 var n=999
48 nAdd = function() {
49 console.log(n += 1)
50 }
51 function f5(){
52 console.log(n)
53 }
54 return f5
55 }
56 //用处一 可以读取函数内部的变量 用处二 让这些变量的值始终保持在内存中
57 var result=f4()
58 result() // 999
59 nAdd() //1000
60 result() //1000
61
62 /*
63 使用闭包的注意点
64 1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
65
66 2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
67 */
68
69 var name = "The Window";
70 var object = {
71 name : "My Object",
72 getNameFunc : function(){
73 var that = this
74 return function(){
75 console.log(that)
76 return that.name;
77 };
78 }
79 };
80 console.log(object.getNameFunc()());
81
82
83 // 定义数字0:
84 var zero = function (f) {
85 return function (x) {
86 return x;
87 }
88 };
89
90 // 定义数字1:
91 var one = function (f) {
92 return function (x) {
93 return f(x);
94 }
95 };
96
97 // 定义加法:
98 function add(n, m) {
99 return function (f) {
100 return function (x) {
101 return m(f)(n(f)(x));
102 }
103 }
104 }
105
106 // 计算数字2 = 1 + 1:
107 var two = add(one, one);
108
109 // 计算数字3 = 1 + 2:
110 var three = add(one, two);
111
112 // 计算数字5 = 2 + 3:
113 var five = add(two, three);
114
115 // 你说它是3就是3,你说它是5就是5,你怎么证明?
116
117 // 呵呵,看这里:
118
119 // 给3传一个函数,会打印3次:
120 (three(function () {
121 console.log('print 3 times');
122 }))();
123
124 // 给5传一个函数,会打印5次:
125 (five(function () {
126 console.log('print 5 times');
127 }))();