闭包

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

 

posted @ 2017-08-05 13:50  咬尾巴的狐狸  阅读(99)  评论(0编辑  收藏  举报