以上代码不论点击第几个都会返回5,原因是i在内存中只有一份,一旦for循环执行完成i就变成了5。我们需要的是每次循环都能自己记住i的值。利用闭包可以作为记住i值的手段,各个i将拥有更长的生存周期。
var nodes = document.getElementsByTagName('div'); for (var i=0, l = nodes.length; i < l; i++){ (function (i) { nodes[i].onclick = function () { console.log(i); } })(i); }我们希望对每次计算调用做一次缓存,以便重复计算的时候能提高效率。
var mult = (function () { var cache = {}; //用来做计算,计算方法将只会被创建一次 var calculate = function () { var a = 1; for (var i = 0, l = arguments.length; i < l; i++){ a = a * arguments[i]; } return a; }; return function () { var args = Array.prototype.join.call(arguments, ','); if(args in cache){ return cache[args]; } return cache[args] = calculate.apply(null, arguments); } })();当我们面对这样的问题时一定首先想到是使用全局变量,但是全局变量存在被后续代码修改的风险。
javascript中并不存在定义私有变量的方法,这样是没有必要的。在一般的OOP编程中我们会这么干:
var extent = { value: 0, callFunc: function () { this.value += 1; console.log(this.value); } }; extent.callFunc(); extent.callFunc(); extent.callFunc();或者使用原型继承这么写:
var Extent = function () { this.value = 0; }; Extent.prototype.callFunc = function () { this.value += 1; console.log(this.value); }; var extent = new Extent(); extent.callFunc(); extent.callFunc(); extent.callFunc();实际上原型继承还是不错的,至少降低value值被修改的风险,但是阅读起来还是不够顺畅,改用闭包实现
var Extent = function () { var value = 0; return{ callfunc: function () { value++; console.log(value); } } }; var extent = Extent(); extent.callfunc(); extent.callfunc(); extent.callfunc(); extent.callfunc();