JS闭包,很流行的概念,听说,不会闭包就不要说会js,今天学习下,http://kb.cnblogs.com/page/110782/讲的比较清楚:
<body> <div id="console"></div> </body> <script> //from:http://kb.cnblogs.com/page/110782/ //一个函数访问了它的外部变量,那么它就是一个闭包 function foo(x) { var tmp = 3; function bar(y) { document.getElementById("console").innerHTML += "<br/>"+ (x + y + (++tmp)); } bar(10); } foo(2); foo(2); foo(2); //一直是16,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function结束。 document.getElementById("console").innerHTML += "<br><br>闭包1"; function returnFoo(x) { var tmp = 3; return function returnBar(y) { document.getElementById("console").innerHTML += "<br/>"+ (x + y + (++tmp)); } } var barReturn = returnFoo(2); // bar 现在是一个闭包 barReturn(10);//16 barReturn(10);//17 barReturn(10);//18 //上面的x是一个字面值(值传递),和JS里其他的字面值一样,当调用foo时,实参x的值被复制了一份,复制的那一份作为了foo的参数x。 document.getElementById("console").innerHTML += "<br><br>闭包2"; barReturn = returnFoo(2);//因为虽然barReturn不直接处于returnFoo的内部作用域,但barReturn还是能访问x和tmp。 barReturn(10);//16 barReturn = returnFoo(2); barReturn(10);//16 barReturn = returnFoo(2); barReturn(10);//16 barReturn(10);//16 document.getElementById("console").innerHTML += "<br><br>闭包3 obj "; //JS里处理object时是用到引用传递的,那么,你调用foo时传递一个object,foo函数return的闭包也会引用最初那个object! function fooObj(x) { var tmp = 3; return function (y) { //alert(x + y + tmp); document.getElementById("console").innerHTML += "<br/>"+ (x + y + (++tmp)); //x.memb = x.memb ? x.memb + 1 : 1; //alert(x.memb); } } var num = new Number(2); var barObj = fooObj(num); // bar 现在是一个闭包 barObj(10); barObj = fooObj(num); barObj(10); barObj = fooObj(num); barObj(10); barObj(10); //闭包经常用于创建含有隐藏数据的函数 var db = (function() { // 创建一个隐藏的object, 这个object持有一些数据 从外部是不能访问这个object的 var data = {}; // 创建一个函数, 这个函数提供一些访问data的数据的方法 return function(key, val) { if (val === undefined) { return data[key] } // get else { return data[key] = val } // set } // 我们可以调用这个匿名方法 返回这个内部函数,它是一个闭包 })(); document.getElementById("console").innerHTML += "<br/>"+ db('x'); // 返回 undefined document.getElementById("console").innerHTML += "<br/>"+ db('x', 1); // 设置data['x']为1 document.getElementById("console").innerHTML += "<br/>"+ db('x'); // 返回 1 // 我们不可能访问data这个object本身 // 但是我们可以设置它的成员 </script>