闭包的用途

闭包必读:https://github.com/mqyqingfeng/Blog/issues/9

练习题

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();
data[1]();
data[2]();
var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = (function () {
    return function() {
      console.log(i);
    }
  })(i);
}

data[0]();
data[1]();
data[2]();
var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = (function (i) {
        return function(){
            console.log(i);
        }
  })(i);
}

data[0]();
data[1]();
data[2]();
var data = [];

for (let i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();
data[1]();
data[2]();

答案: 3,3,3

3,3,3

0,1,2

0,1,2

转载自:https://www.cnblogs.com/yunfeifei/p/4019504.html

 什么是闭包?

 MDN对闭包的解释如下:

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

function outer() {
    const a = 10;
    function inner() {
        return a;
    }
    return inner;
}

var innerFunc = outer();
console.log(innerFunc()); // 输出 10

我们执行outer返回的inner函数,inner函数内部引用了outer函数中的变量a. outer函数执行结束后,变量a不会被销毁,而是继续留在内存中。

闭包在前端常用的使用场景: 

  • 函数句柄
  • 回调函数
  • 函数式声明

1、结果缓存

我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,

那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值;如果找到了,直接返回查找到的值即可。

之所以闭包可以做到这一点,使因为它不会释放外部活动对象的引用,从而函数内部的值可以得以保留。

var CachedSearchBox = (function(){    
    var cache = {},    
       count = [];    
    return {    
       attachSearchBox : function(dsid){    
           if(dsid in cache){//如果结果在缓存中    
              return cache[dsid];//直接返回缓存中的对象    
           }    
           var fsb = new uikit.webctrl.SearchBox(dsid);//新建    
           cache[dsid] = fsb;//更新缓存    
           if(count.length > 100){//保正缓存的大小<=100    
              delete cache[count.shift()];    
           }    
           return fsb;          
       },    
     
       clearSearchBox : function(dsid){    
           if(dsid in cache){    
              cache[dsid].clearSelection();      
           }    
       }    
    };    
})();    
     
CachedSearchBox.attachSearchBox("input");

2.封装

var person = function(){    
    //变量作用域为函数内部,外部无法访问    
    var name = "default";       
       
    return {    
       getName : function(){    
           return name;    
       },    
       setName : function(newName){    
           name = newName;    
       }    
    }    
}();    
     
print(person.name);//直接访问,结果为undefined    
print(person.getName());    
person.setName("abruzzi");    
print(person.getName());    
   
得到结果如下:  
   
undefined  
default  
abruzzi

 

posted @ 2019-03-20 10:02  cecelia  阅读(171)  评论(0编辑  收藏  举报