日期:2014-05-16 浏览次数:20444 次
?
?? ? ?除了模拟类的私有变量和私有方法。闭包还可用来模拟类的静态变量和方法。
?
除了再次利用js的闭包特性,还需要借助js语法上的一些特点。看下面一段代码:
?
?
var MyNamespace = {}; // 定义命名空间 MyNamespace.TreeItem = (function(){ //使用闭包产生的私有静态变量,不可被外部访问 var numTreeItems = 0; //使用闭包产生的私有静态方法,不可被外部访问 function counter(){ numTreeItems ++; console.log("Created "+numTreeItems+" tree items!"); } //该匿名函数的引用将被赋予MyNamespace.TreeItem return function(){ //使用闭包产生的私有类变量,不可被外部访问 var label; //可访问私有变量,也可被外部访问的方法 this.setLabel = function( newLabel ){ label = newLabel; }; this.getLabel = function(){ return label; }; //该方法用来累计实例的数量 counter(); } })(); //在函数定义的末尾加上括号,表示该函数在定义后立即执行 //不可访问私有变量以及其它公共方法的静态公共方法 MyNamespace.TreeItem.clone = function(otherInstance){ }; MyNamespace.TreeItem.prototype = { // 不可访问私有变量,但可访问其它公共方法的公共方法 print: function(){ console.log(this.getLabel()); } }; var treeItem1 = new MyNamespace.TreeItem(); // print 1 var treeItem2 = new MyNamespace.TreeItem(); // print 2?
?
?
执行上述代码后,浏览器控制台将会输出如下字符串:
?
?Created 1 tree items!
?Created 2 tree items!
?
之所以把上述一些js变量和函数称为“静态”,是借用了Java的提法。
?
这些“静态”变量和方法被保存在闭包中,在内存中是唯一的,
?
不会随着该函数副本的增加而增加。如果一个函数需要被实例化多次,
?
但其中的一些内部函数并不需要访问任何实例数据,从节省内存的角度考虑,
?
可采用上述构建静态函数的方法。js中的“静态”概念,有一点与Java不同:
?
如果上述TreeItem被设为null,即不再有引用指向它,那么它的闭包也将消失,
?
保存在闭包中的静态变量和方法,也将被垃圾回收器择机回收。
?
?
var MyNamespace = {}; MyNamespace.TreeItem = (function() { var numTreeItems = 0; function counter() { numTreeItems ++; console.log("Created "+numTreeItems+" tree items!"); //alert(numTreeItems); } return counter; })(); var treeItem1 = new MyNamespace.TreeItem(); var treeItem2 = new MyNamespace.TreeItem(); var treeItem3 = MyNamespace.TreeItem(); var treeItem4 = MyNamespace.TreeItem();