DANCE WITH JAVA

          開發出高質量的系統

          常用鏈接

          統計

          積分與排名

          好友之家

          最新評論

          面向對象(OOP)方法使用 JavaScript

          private variables:原始的定義變量的方法 var
          private functions:通過 var functionName=function(){}聲明

          privileged methods: 通過this.methodName=function(){}聲明
          privileged properties:通過 this.variableName來聲明
          (有些地方把privileged properties叫做public properties,但我感覺無論是按照
          定義寫法,還是為了便于理解都叫privileged properties更好些。更便于對比對稱記憶)

          prototype methods :通過Classname.prototype.methodname=function(){}來聲明
          (有些地方叫public method,同樣和上邊一樣的理由,這里改叫prototype method)
          prototype properties:通過 classname.prototype.propertyName=somevalue來聲明

          static properties: 通過classname.propertyName=somevalue定義
          static method :通過classnamne.methodName來聲明

          說明:有些地方(例如我看的文檔中)把privileged properties和prototype method叫成
          public properties 和public method,不知道為什么這樣叫。這樣命名后造成的問題是
          1,privileged method沒有對應的privileged properties
          2,prototype properties沒有對應的prototype method
          3,public method和public properties的定義方式又不對稱

          下邊解釋一下幾種情況:
          1,private:定義在類內部,只能被類內部的方法調用,例如privileged(見實例一中的(1)(2))
          2,priviledged :定義在類內部,能被任何調用,在調用上有點類似Java中
          的非靜態public方法(見實例一中的(3))
          3,prototype:這個概念不太好理解,在執行上有點像java的clone,只在類初始化的時候
          執行一次。每次建立實例的時候不執行。能被繼承。
          4,static: 有點類似java中的靜態。各實例共享,不能被繼承
          實例一如下:

          <script>
                  function Pet(name,color)
          {
                      
          //priviledged properties
                      this.name=name;
                      
          this.color=color;
                      
          //private properties
                      var type="animal";
                      
          //private method
                      var run2 = function(){
                          run(type);
                      }

                      var run 
          = function(mType){
                          alert(color
          +" "+name+" is runing("+mType+")");
                      }

                      
          //priviledged method
                      this.callRun = function(){
                          
          /*(1)priviledged method can visit private properties and private method*/
                          run(type);
                      }

                  }


                  Pet.prototype.callPrivateRun 
          =function(pet){
                  
          /*(2)can not call run*/            
                      
          //pet.run2();
                  /*(3)can call priviledge method and priviledge properties*/
                      pet.callRun();
                  }


                  function test()
          {
                      var pet 
          = new Pet("pig","black");
                      pet.callRun();
                      alert(
          "prototype");
                      pet.callPrivateRun(pet);

                  }

                  window.onload
          =test;
              
          </script>
          繼承與覆寫
          實例二演示了繼承、覆寫
          另外javascript不支持多態性
          <script>
                  function Pet()
          {
                      
          //name
                      this.name=null;
                      
          this.getName = function() {return this.name;};
                      
          this.setName = function(newName) {this.name = newName;};
                      
          //abstract method
                      this.eat = null;
                  }

                  
          /*cat inherit from Pet*/
                  Cat.prototype 
          = new Pet();
                  function Cat()
          {
                      
          //implement the abstract method
                      this.eat = function(food){
                          alert(
          "The cat (" + this.name+ ") is eating " + food);
                      }

                  }

                  
          /*dog inherit from Pet*/
                  function Dog()
          {
                      
          //implements the abstract method
                      this.eat = function(food){
                          alert(
          "The dog (" + this.name+ ") is eating " + food);
                      }

                  }

                  Dog.prototype 
          = new Pet();
                  
          /*Hound inherit from dog*/
                  Hound.prototype 
          = new Dog()
                  function Hound()
          {
                      
          //override
                      this.eat = function(food){
                          alert(
          "The Hound (" + this.name+ ") is eating " + food);
                      }

                  }


                  function test()
          {
                      var cat 
          = new Cat();
                      cat.setName(
          "mimi");
                      cat.eat(
          "fish");
                      var dog 
          = new Dog();
                      dog.setName(
          "wangwang");
                      dog.eat(
          "bone");
                      var hound 
          = new Hound();
                      hound.setName(
          "hali");
                      hound.eat(
          "rabbit");            
                  }

                  window.onload
          =test;
              
          </script>

          posted on 2007-05-22 18:07 dreamstone 閱讀(1868) 評論(3)  編輯  收藏 所屬分類: 腳本語言javascript

          評論

          # re: 面向對象(OOP)方法使用 JavaScript 2007-05-22 23:50 熱門單曲

          多謝樓主分享 頂了  回復  更多評論   

          # re: 面向對象(OOP)方法使用 JavaScript 2007-05-23 10:21 BeanSoft

          不錯, 收藏了!  回復  更多評論   

          # re: 面向對象(OOP)方法使用 JavaScript[未登錄] 2007-05-23 17:15 teddy

          不錯了,其實prototype是最好理解的。

          在JavaScript中,如下:
          function A() {
          this.t1 = "ffffff";
          this.t2 = function (msg) {
          alert(msg);
          };
          };

          A.prototype.p1 = "xxxx";

          A.prototype.f1 = function () {
          do something....
          };

          其實p1,f1是對function的prototype對象的操作,大家要明白,function
          也是一個對象,對象也有屬性,而prototype就是function的屬性,該屬性
          也是一個對象,不同之處是,function在做為類定義的時候,創建類實例的
          過程(new的過程)要參照它的prototype對象,把prototype對象的所有
          屬性(也就是Java里的成員,包括成員變量和成員函數)都復制到新的對象
          中去,所以可以看出prototype就是模板,而這個模板是在new一個對象之
          前就已經存在了。

          上面的JavaScript就好像在定義一個Java類,不同的是JVM必須把類本身
          載入虛擬機,然后才允許Java使用者new對象。而JavaScript,可以先建立
          類(也就是定義function A的部分),然后再決定類中有什么成員(也就是
          往A的prototype里追加成員部分)。

          而在function A的函數體內定義的this成員,可以理解為‘后’綁定成員。
          可以這么理解,在new A()的時候JavaScript建立了一個臨時對象,
          把A.prototype的所有成員復制到臨時對象中,然后再把函數A中
          定義的this成員也綁定到臨時對象中,然后把臨時對象返回給用戶。
          下面是模擬JavaScript的new關鍵字的處理偽過程:
          //建立臨時對象
          var tobj = {};
          //復制prototype
          for (var key in A.prototype)
          tobj[key] = A.prototype[key];
          //綁定函數體內的this成員(這個過程沒有辦法模擬)
          return tobj to user;

          之所以存在function內部定義的this成員,以及prototype的成員是
          有原因的。由于JavaScript的類在構造時是可以傳遞構造參數的,
          所以,this成員的行為可能由于參數的不同而不同。這也就是需要后
          綁定的原因了。在看下一個例子:
          function AA(val1,val2) {
          this.test1 = function() {
          alert(val1);
          };

          this.test2 = val2 ? function () { return this.test1;} : function () { return 456; };

          this.test3 = val1 ? val1 : function () {alert("no val1");};
          }

          這個例子很好的說明了后綁定的實際使用價值,所以后綁定對于成員
          函數來說是非常有用的,對于成員變量來說其實沒什么實際用處。
          唯一不同的是,this成員在每次new對象時都要被JavaScript引擎解析,
          原因很簡單,根據不同的構造參數,使它們在運行期的行為可能有很大
          的不同。而prototype的成員就不會每次都解析,第一次定義prototype
          成員時才解析,以后可以直接引用prototype成員,并且更改了prototype
          成員,所有已經建立的實例對象的相應成員都會被更改。

          在運行期可以通過'對象名.成員名'來更改成員,這種方式可以更改this成員
          和prototype成員的默認定義,但是更改只限于自身對象,因為JavaScript
          和Java一樣,也是傳值,對象的引用也是一個地址值,所以new一個對象后,
          prototype的成員也被復制到那個對象上了,再更改那個對象的成員,只會
          影響那個對象自身,其他從同一個類new出來的對象都不會有任何變化。

          不能通過運行期設置'類.prototype.成員名'來覆蓋this同名成員,這樣做沒有
          任何效果。

          通過復制一個對象的所有屬性到一個新對象,是不能通過修改prototype成員
          來修改新對象的成員行為,因為新對象不是通過原來對象的類new出來的。
          通常的復制方法如下:
          var tobj = {};
          for (var key in otherObj)
          tobj[key] = otherObj[key];
          看似tobj和otherObj的行為是一致的,他們不是一個類new出來的。

          最后再談談prototype的constructor成員,該成員是對一個類的構造函數的引用,
          在類定義的初期,如果一個類沒有從其他別的類那里繼承,該類的prototype.constructor屬性保存的是該類自身的引用,如果該類從別的類
          繼承,那么它的constructor屬性就保存了父類的constructor引用,
          一般constructor沒有什么用處,但可以通過它來取得他的類的信息,
          就像Java里的對象都有getClass()方法,constructor就是干這個用的。
          有它的好處是,再運行期可以改變所有同類對象的成員行為,如:
          someObj.constructor.prototype.somePrototype = function () {
          other process ....
          }

          因此好的習慣是在繼承之后把prototype的constructor成員設置一下,
          否則會把父類的prototype成員改掉,那樣程序的行為就不可預知了。
          如:
          function classA() {

          }

          classB.prototype = new classA();
          classB.prototype.constructor = classB;

          至此所有和prototype有關的都介紹完畢,歡迎大家指正批評。

          to 作者 : 本來我想少說兩句,但是說了那么多,其實應該再開一篇
          blog,但是我自己不寫blog,只能在你這里寫兩句了,留著你自己再
          整理以下吧。  回復  更多評論   

          主站蜘蛛池模板: 麟游县| 互助| 贵阳市| 大关县| 屯昌县| 兰坪| 石狮市| 儋州市| 库尔勒市| 浮梁县| 寿宁县| 皋兰县| 清镇市| 句容市| 康平县| 永春县| 泰来县| 辛集市| 桐梓县| 曲水县| 溧阳市| 武邑县| 雷州市| 江西省| 华阴市| 东平县| 阳春市| 九寨沟县| 铜川市| 太湖县| 化州市| 巴里| 定陶县| 浦东新区| 东安县| 西宁市| 沙河市| 宣化县| 肥乡县| 龙井市| 天门市|