posts - 297,  comments - 1618,  trackbacks - 0
           

          說明:本文為《JavaScript高級程序設計》第4章學習筆記。

          一.             繼承機制實例

          幾何形狀只有兩種,即橢圓形和多變形。圓是橢圓形的一種,它只有一個焦點。三角形、矩形和五邊形都是多邊形的一種,具有不同數量的邊。正方形是矩形的一種,所有的邊等長。這就構成了繼承關系。

          形狀是橢圓形和多邊形的基類。圓形繼承了橢圓形,因此圓形是橢圓形的子類,橢圓形是圓形的超類

          二.             繼承機制的實現

          要用ECMAScript實現繼承機制,首先從基類入手。所有開發者定義的類都可以作為基類。出于安全原因,本地類和宿主類不能作為基類,這樣可以防止編譯過的瀏覽器級的代碼,因為這些代碼可以被用于惡意攻擊。

          選定基類后,就可以創建它的子類了。是否使用基類完全由你決定。有時,你可能想創建不能直接使用的基類,它只是用戶給予類公共通用的函數。在這種情況下,基類被看作抽象類

          1.繼承的方式

          JavaScript中的繼承機制并不是明確規定的,而是通過模仿實現的。開發者可以自己決定最適用的繼承方式。

          1)對象冒充

          原理:構造函數使用this關鍵字給所有屬性和方法賦值。因為構造函數只是一個函數,所以可使ClassA的構造函數成為ClassB的方法,然后調用它。ClassB就會收到ClassA的構造函數定義的屬性方法。

          Eg. 

          function ClassA(sColor) {
                   
          this.color = sColor;
                   
          this.sayColor = function() {
                 alert(
          this.color);
          }

          }


          function ClassB(sColor, sName) {
                   
          this.newMethod = ClassA;
                   
          this.newMethod(sColor);
                   
          delete this.newMethod;
                   
          this.name = sName;
                   
          this.sayName = function() {
                 alert(
          this.name);
          }
               
          }


          2)call()方法

          call()方法是與經典的對象冒充方法最相似的方法。它的第一個參數用作this的對象,其他參數都直接傳遞給函數本身。

          Eg. 可將上例中的ClassB改成如下后,可達到先前同樣的效果: 

          function ClassB(sColor, sName) {
                  ClassA.call(
          this, sColor);
           
          this.name = sName;
           
          this.sayName = function() {
          alert(
          this.name);
          }

          }

           

          3)apply()方法

          該方法有兩個參數,用作this的對象要傳遞給的參數的數組。

          Eg.

          function sayColor(sPrefix, sSuffix) {
                    alert(sPrefix 
          + this.color + sSuffix);
          }
          ;
          var obj = new Object();
          obj.color 
          = "red";
          sayColor.apply(obj, 
          new Array("The color is "", a very nice color indeed."));

          可將上述的ClassB修改為如下這樣:

          function ClassB(sColor, sName) {
                 ClassA.apply(
          thisnew Array(sColor));
                 
          this.name = sName;
                 
          this.sayName = function() {
                 alert(
          this.name);
          }
          ;
          }

           

          4)原型鏈

          Prototype對象是個模板,要實例化的對象都以這個模板為基礎。總而言之,prototype對象的任何屬性和方法都被傳遞給那個類的所有實例。原型鏈利用這種功能來實現繼承機制。

          Eg.

          function ClassA() {
          }


          ClassA.prototype.color 
          = "red";

          ClassA.prototype.sayColor 
          = function() {
                   alert(
          this.color);
          }
          ;

          function ClassB() {
          }


          ClassB.prototype 
          = new ClassA();
          ClassB.prototype.name 
          = "";
          ClassB.prototype.sayName 
          = function() {
                   alert(
          this.name);
          }
          ;

          原型鏈的弊端是不支持多重繼承。記住,原型鏈會用另一類型的對象重寫類的prototype屬性。

          5)混合模式

          對象冒充的主要問題是必須使用構造函數的方式,這不是最好的選擇。不過如果使用原型鏈,就無需使用構造函數了。如果將這兩種方式混合起來,將會達到更好的效果。

          Eg.

           fuction ClassA(sColor) {
              
          this.color = sColor;
          }


          ClassA.prototype.sayColor 
          = function() {
              alert(
          this.color);
          }
          ;

          function ClassB(sColor, sName) {
              ClassA.call(
          this, sColor);
              
          this.name = sName;
          }


          ClassB.prototype 
          = function() {
              alert(
          this.name);
          }
          ;

            調用代碼如下所示:

          var objA = new ClassA("red");
          var objB = new ClassB("blue""AmigoXie");
          objA.sayColor();
          objB.sayColor();
          objB.sayName();

           

          2.一個更實際的例子

          下面講一個PolygonTriangleRectangle的例子。

          1)創建基類Polygon

          Eg. 

           function Polygon(iSides) {
                   
          this.sides = iSides;
          }


          Polygon.prototype.getArea 
          = function() {
                  
          return 0;
          }
          ;


           

          2)創建子類

          三角形Triangle的內容如下:

          function Triangle(iBase, iHeight) {
                  Polygon.call(
          this3);
                  
          this.base = iBase;
                  
          this.height = iHeight;
          }


          Triangle.prototype 
          = new Polygon();
          Triangle.prototype.getArea 
          = function() {
                  
          return 0.5 * this.base * this.height;
          }
          ;

          Rectangle的ECMAScript代碼如下:

          function Rectangle(iLength; iWidth) {
                  Polygon.call(
          this4);
                  
          this.length = iLength;
                  
          this.width = iWidth;
          }


          Rectangle.prototype 
          = new Polygon();
          Rectangle.prototype 
          = function() {
                  
          return this.length * this.width;
          }
          ;

           

          3)測試代碼 

          var triangle = new Triangle(124);
          var rectangle = new Rectangle(2210);
          alert(triangle.sides);
          alert(triangle.getArea());
          alert(rectangle.sides);
          alert(rectangle.getArea());

           

          4)采用動態原型方法如何?

          function Polygon(iSides) {
                  
          this.sides = iSides;
                  
          if (typeof Polygon._initialized == "undefined"{
                 Polygon.prototype.getArea 
          = function() {
                 
          return 0;
          }
          ;

          Polygon._initialized 
          = true;
          }

          }


          function Triangle(iBase, iHeight) {
                  Polygon.call(
          this3);
                  
          this.base = iBase;
                  
          this.height = iHeight;
                  
          if (typeof Triangle._initialized == "undefined"{
                 Triangle.prototype 
          = new Polygon();
                 Triangle.prototype.getArea 
          = function() {
                 
          return 0.5 * this.base * this.height;
          }
          ;

          Triangle. _initialized 
          = true;
          }

          }


          Triangle.prototype 
          = new Polygon();

           

          三.             小結

          本章介紹了ECMAScript中用對象冒充和原型鏈實現的繼承概念。學會結合使用這些方式才是建立類之間的繼承機制的最好方式。

          posted on 2007-09-04 08:59 阿蜜果 閱讀(959) 評論(3)  編輯  收藏 所屬分類: Javascript


          FeedBack:
          # re: JavaScript學習筆記——繼承
          2007-09-04 13:48 | freeman
          好東西! 我先頂一下,不知道有沒有數據庫設計的東東,小弟正在學那個。  回復  更多評論
            
          # re: JavaScript學習筆記——繼承
          2007-09-04 15:54 | mortal
          姐姐,有點問題請教下,
          <object>
          <param name="enableContextMenu" value="0">
          <param name="fullScreen" value="0">
          </object>
          假如我要取得enableContextMenu的值,請問怎么用js取得?  回復  更多評論
            
          # re: JavaScript學習筆記——繼承
          2007-09-10 11:32 | 冬虎
          小丫頭,不錯,只是照片有點糊,看不清臉,能不能換張清晰點的吼吼,  回復  更多評論
            
          <2007年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

                生活將我們磨圓,是為了讓我們滾得更遠——“圓”來如此。
                我的作品:
                玩轉Axure RP  (2015年12月出版)
                

                Power Designer系統分析與建模實戰  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊

          關注blog

          積分與排名

          • 積分 - 2295550
          • 排名 - 3

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 溧水县| 治多县| 柞水县| 南康市| 东阿县| 临夏市| 汶上县| 通辽市| 泸溪县| 环江| 庆安县| 龙陵县| 定州市| 巴南区| 新河县| 漳平市| 古丈县| 莱芜市| 新密市| 宜春市| 井冈山市| 邹城市| 玉溪市| 铜鼓县| 阿拉善右旗| 乌什县| 台江县| 玉山县| 耿马| 石渠县| 南通市| 广元市| 响水县| 防城港市| 仪征市| 麻城市| 平罗县| 岢岚县| 宝清县| 内江市| 延安市|