关于js闭包影响性能的讨论

时间:2021-10-10 22:40:59
  1.  

    上面的代码很简单,只是把数据成员a的访问器(setter/ getter),放在了构造函数中。a使用var声明,外面不能直接访问a。get_a和set_a都用this来使得这两个函数与类对象关联,并且外面可见。
  2. 上面的方法很有技巧,但我从没有这样做过,微软的AJAX.NET也没有利用闭包来实现访问控制。原因是它要占用更多的内存,下面说说它为什么要占用更多的内存。
  3. 首先,我们使用原型(prototype)来定义一个类
闭包有许多有趣的用途,Javascript的两个特征使它这么有趣:1. function是一个对象,它跟数组,Object一样,地位平等。2. Javascript变量作用域范围。《Javascript权威指南》对这两点有深入的讲解。

闭包有一个著名的用途就是实现面向对象的访问控制。也就是c++, c#, java等面向对象的private, public访问控制。先看一段示例代码

4
1

undifinite

首先,我们使用原型(prototype)来定义一个类
 
  1. <script type="text/javascript">
  2. function ClassA(){
  3.     var a = 4;
  4.     this.get_a = function(){
  5.         return a;
  6.     };
  7.     this.set_a = function(value){
  8.         a = value;
  9.     };
  10. }
  11. var v = new ClassA();
  12. document.write(v.get_a()+"<br />"); //显示4
  13. v.set_a(1);
  14. document.write(v.get_a()+"<br />"); //显示1
  15. alert(v.a); //显示undefined
  16. </script>

prototype fun1

prototype fun1

modify function

modify function

modify a's method

modify function

 

从上面的运行结果可以看出,使用prototype定义的类,实例化出来的对象都共享同一个方法,一旦原型改变了,会影响全部对象。而一个对象修改了自身的方法,系统会执行copy on write,把对象指向新的方法而不会影响其他对象。

 

 

再看看以下这一段:

  1. <script type="text/javascript">
  2. function ClassA(){
  3.     this.fun1 = function(){
  4.         document.write("object function <br />");
  5.     };
  6. }
  7. var a = new ClassA();
  8. var b = new ClassA();
  9. a.fun1();
  10. b.fun1();
  11. ClassA.prototype.fun1 = function(){
  12.     document.write("modify object function <br />");
  13. }
  14. a.fun1();
  15. b.fun1();
  16. a.fun1 = function(){
  17.     document.write("modify a's function <br />");
  18. }
  19. a.fun1();
  20. b.fun1();
  21. </script>

object function
object function
object function
object function
modify a's function
object function

 

 

从运行结果可以看到,闭包的结果是每个对象都拥有独立的方法,即使对象之间的方法的实现一模一样。这样会造成多余的内存浪费。试想想,如果一个使用闭包的类实例了许多个对象,那么会浪费多少内存?