1. 什么是闭包?
参考MDN。
2. 闭包的使用示例
2.1 示例1
1 <div>1</div> 2 <div>2</div> 3 <div>3</div> 4 <script> 5 var nodes = document.getElementsByTagName('div'); 6 for (var i = 0, len = nodes.length; i < len; i++) { 7 /* 注意这里 */ 8 (function (i) { 9 10 nodes[i].onclick = function () { 11 console.log(i + 1); 12 }; 13 14 })(i); 15 16 }; 17 </script>
2.2 延伸
1 var Type = {}; 2 for (var i = 0, type; type = ['Number', 'String', 'Boolean', 'Array', 'Function', 3 'RegExp', 'Date', 'Undefined', 'Null','Error'][i++];) { 4 (function (type) { 5 Type['is' + type] = function (obj) { 6 return Object.prototype.toString.call(obj) === '[object ' + type + ']'; 7 } 8 })(type); 9 };
说明:对于本例来说仅能判断类型,并不能保证类型的合法性,如判断Date如下所示:
1 function isValidDate(d) { 2 if (Object.prototype.toString.call(d) !== "[object Date]") { 3 return false; 4 } 5 return !isNaN(d.getTime()); 6 }
3. 闭包的更多作用及示例
3.1 封装变量
在闭包块中实现“私有变量”
1 var mult = (function () { 2 var cache = {}, // “制表法”缓存结果集,避免重复的运算 3 // 封闭calculate 函数 4 calculate = function () { 5 var a = 1; 6 for (var i = 0, l = arguments.length; i < l; i++) { 7 a = a * arguments[i]; 8 } 9 10 return a; 11 }; 12 13 return function () { 14 var args = Array.prototype.join.call(arguments, ','); 15 if (args in cache) { 16 return cache[args]; 17 } 18 19 return cache[args] = calculate.apply(null, arguments); 20 }; 21 })();
MDN的例子用闭包模拟私有方法,也是模块模式的基础。
3.2 延续局部变量的寿命
1 var report = function( src ){ 2 var img = new Image(); 3 img.src = src; 4 }; 5 report( 'www.xxx.com/stat' );