闭包实例
严格来说,闭包需要满足三个条件:【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
浙公网安备 33010602011771号