1. 什么是闭包?
参考。
2. 闭包的使用示例
2.1 示例1
1122334
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' );
为了解决函数局部变量在函数执行后立即被销毁的问题,可以用闭包来保存对局部变量的引用以达到延续局部变量生命周期。
1 var report = (function () { 2 var imgs = []; 3 4 return function (src) { 5 var img = new Image(); 6 imgs.push(img); 7 img.src = src; 8 } 9 })();10 11 report('www.xxx.com/stat');
3.3 闭包和面向对象设计
1 // 闭包写法 2 var extent = function () { 3 var value = 0; 4 return { 5 call: function () { 6 value++; 7 console.log(value); 8 } 9 };10 };11 var extent1 = extent(),12 extent2 = extent();13 extent1.call(); // 输出:114 extent1.call(); // 输出:215 extent1.call(); // 输出:316 17 extent2.call(); // 输出:118 19 var Extent = function () {20 this.value = 0;21 };22 23 // 面向对象的写法 24 Extent.prototype.call = function () {25 this.value++;26 console.info(this.value);27 };28 var myExtent1 = new Extent();29 myExtent1.call();30 myExtent1.call();31 myExtent1.call();32 33 var myExtent2 = new Extent();34 myExtent2.call();
说明:本文代码来自《JavaScript设计模式与开发实践》和网络。