闭包实例

严格来说,闭包需要满足三个条件:【1】访问所在作用域;【2】函数嵌套;【3】在所在作用域外被调用

1、闭包表现形式

当function里嵌套function时,内部的function可以访问外部function里的变量。 

function foo(x) { 
    var tmp = 3; 
    function bar(y) { 
        alert(x + y + (++tmp)); 
    } 
    bar(10); 
} 
foo(2) 

  不管执行多少次,都会alert 16,因为bar能访问foo的参数x,也能访问foo的变量tmp。 
  但,这还是闭包,只是没表现出来,chrome里可以看出closure。当你return的是内部function时,就是一个闭包(表现出来的闭包)。内部function会close-over外部function的变量直到内部function结束。 

function foo(x) { 
    var tmp = 3; 
    return function (y) { 
        alert(x + y + (++tmp)); 
    } 
} 
var bar = foo(2); // bar 现在是一个闭包 
bar(10); 

  上面的脚本最终也会alert 16,因为虽然bar不直接处于foo的内部作用域,但bar还是能访问x和tmp。 
  但是,由于tmp仍存在于bar闭包的内部,所以它还是会自加1,而且你每次调用bar时它都会自加1. 

 

2、结果缓存

我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
 
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");

 

 
这样我们在第二次调用的时候,就会从缓存中读取到该对象。
 
3.简单的封装
var myModule= function () {
    var private = 123
    return {
        foo: function(){
        }
    };
}(); 

4.你真的懂闭包?

测试1.

 

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());

 

测试2

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());

 

答案1  The Windw     因为 this 是 Window

答案2   My Object   国为 that 是object that是闭包用到的变量, 如果 that很大,那么恭喜你,你走进了闭包的大坑,内存泄露很严重

 

5、用自执行函数的闭包

原例子不用我说了吧

var btns = document.getElementByClass('btn')
for(var i = 0, len = btns.length; i < len; i++) {
        btns[i].onclick = function() {
            alert(i);  //  alert 10
        }
}

用自执行函数包一层,闭包


var btns = document.getElementByClass('btn')
for(var i = 0, len = btns.length; i < len; i++) {
    (function(i) {
    // 这里有个 i是闭包函数用到的 i btns[i].onclick
= function() { alert(i); //函数里的 i } }(i)) }

 

更多请看  http://www.cnblogs.com/xiaohuochai/p/5730085.html

posted on 2017-09-01 10:57  至尊宝第一代  阅读(196)  评论(0)    收藏  举报