天天看点

Learning Javascript OOP II

  1. 作用域、嵌套函数和闭包
    1. 真正的私有方法和属性:在Javascript中,只有函数才有作用域 。也就是说,在一个函数内部声明的变量在函数外问无法访问。但是定义在这个函数中的变量可以被内嵌在这个函数中的内嵌函数 。所以这样就可以达到私有方法和属性的效果.
      function foo() {
         var i = 2;
      
         // private function
         function bar() {
            i *= 2;
         }
      
         bar();
         return i;
      }
      
      以及
      
      function foo() {
         var i = 2;
      
         // private function
         function bar() {
            i *= 2;
            return i;
         }
      
         return bar();
      }
      var baz = foo(); // baz is now a reference to function bar.
      baz(); // returns 4
      baz(); // returns 8
      baz(); // returns 16
      
      var blat = foo(); // blat is another reference to bar.
      blat(); // return 4
             
  2. 什么时候应该在构造函数里定义方法(特权方法Privileged methods):
    var Persion = function(name, age) {
       var name;
       
       this.setName(nameParam) {
          name = nameParam;
       }
    }      
     什么时候应该用prototype方式定义方法:
    var Person = function(name, age) {
       var name;
       var age;
    
       this.getName() {
          return name;
       }
    
       this.getAge() {
          return age;
       }
    
    };
    
    Person.prototype = function() {
       toString : function() {
          return this.getName() + " is " + this.getAge() + " years old."
       }
    }      
      prototype定义的方法没法访问到私有变量和方法, 而且prototype定义的方法在内存中只存在一份,而特权方法Privileged methods会在创建多个实例后在内存中存在多份,从而会降低性能。另外私有属性和方法不能被子类重用,所以当要在子类重用方法或属性时,对方法和属性的作用域限制就不能用闭包来实现了。
  3. 一个完整的JS类的例子(采闭包方式实现)
    var Person = (function(){
       
       // const variable(This variable won't be changed, so it's final.)
       var EIGHTEEN = 18;
    
       // private static variable
       var personCount = 0;
    
       // private static method
       function isAdult(age) {
          return age >= EIGHTEEN ? true : false;
       }
    
       // constructor
       return function(nameParam, ageParam) {
          // private instance variable
          var name, age;
    
          // public instance method(Privileged method)
          this.setName = function(nameParam) {
             name = nameParam;
          };
          this.getName = function() {
             return name;
          };
          this.setAge = function(ageParam) {
             if (isAdult(ageParam)) {
                age = ageParam;
             }
             age = EIGHTEEN;
          };
          this.getAge = function() {
             return age;
          };
    
          // init properties or do some about initializing work
          personCount++;
    
          this.setName(nameParam);
          this.setAge(ageParam);
       }
    })();
    
    // public static method for Person class
    Person.doSomething = function() {
       //TODO......
    };
    
    // Create Person instance
    Person handy_wang = new Person("handy.wang", 18);
    handy_wang.setName("Wang-Jiangshan");
    handy_wang.setAge(24);
    Person.doSomething();      

继续阅读