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 }))();