Dev@Free

          zJun's Tech Weblog

          在javascript中實(shí)現(xiàn)繼承關(guān)系

          意譯自KevLinDev上一篇文章,才疏學(xué)淺,望指正,英文原文可到這里查看。

              javascript腳本語言是支持面向?qū)ο缶幊?Object Oriented Programming )的,只是javascript實(shí)現(xiàn)的方式比較特別,與C++和java中的實(shí)現(xiàn)方式不同。在javascript中我們需要借助prototype對象來訪問父類的方法,下面將討論在javascript中實(shí)現(xiàn)OOP中最基本的特征關(guān)系 --- 繼承

          首先,我們從最基本的開始:在javascript中創(chuàng)建對象。創(chuàng)建一個對象包括2步:
          1) 創(chuàng)建一個和你想要創(chuàng)建的對象同名的函數(shù)(這里可以把這個函數(shù)理解為java中的構(gòu)造函數(shù));
          2) 通過調(diào)用 new 上面創(chuàng)建的函數(shù)名 的方式創(chuàng)建一個對象實(shí)例;
          // 創(chuàng)建同名函數(shù)
          function Person(first, last) {
              
          this.first =
           first;
              
          this.last  =
           last;
          }
          // 創(chuàng)建實(shí)例

          var person = new Person("John""Dough");

          注意:構(gòu)造函數(shù)中的this指針指向當(dāng)前的創(chuàng)建的對象,這與java中的表示是一致的。通過this指針我們可以操作對象的屬性。

          然后,設(shè)置對象的方法:
          Person.prototype.toString() {
              
          return this.first + " " + this
          .last;
          }
          alert( person.toString() ); 
          // displays "John Dough"

          alert( person ); // alert函數(shù)將默認(rèn)調(diào)用toString()函數(shù)

          在這里我們用到了javascript中的prototype屬性。所有的javascript對象都擁有一個prototype屬性,javascript就是通過這個屬性來實(shí)現(xiàn)繼承關(guān)系的。具體的實(shí)現(xiàn)機(jī)制是這樣的:當(dāng)你訪問一個對象的屬性時,編譯器將先查找對象的屬性看有沒有匹配的。如果沒有找到,將繼續(xù)查找這個對象的prototype屬性所指的對象,看是否存在匹配的屬性。如果還是沒有找到,編譯器將檢查當(dāng)前對象的prototype是否擁有prototype屬性,如果有將繼續(xù)查找下去。以此類推,直到查找完所有的prototype屬性。
          從這個過程不難看出,存在著一個類似于繼承的訪問鏈,可以把prototype對象指向我們要繼承的父類,以此來訪問父類的方法。

          接下來,我們新建一個類Employee來繼承上面的Person類,并且新增一個屬性id,在Employee的構(gòu)造函數(shù)中只是初始化屬性id,而父類中的屬性將由Person的構(gòu)造函數(shù)類設(shè)置:
          function Person(first, last) {
          if ( arguments.length > 0
           )
              
          this
          .init(first, last);
          }

          Person.prototype.init 
          = function
          (first, last) {
              
          this.first =
           first;
              
          this.last  =
           last;
          }

          Employee.prototype 
          = new
           Person();
          Employee.prototype.constructor 
          =
           Employee;
          Employee.superclass 
          =
           Person.prototype;

          function
           Employee(first, last, id) {
              
          if ( arguments.length > 0
           )
                  
          this
          .init(first, last, id);
          }

          Employee.prototype.init 
          = function
          (first, last, id) {    
              
          // Call superclass method

              Employee.superclass.init.call(this, first, last);

              
          // init properties

              this.id = id;
          }

          可以看到,我們把初始化屬性的操作提取出來放到了一個init函數(shù)中,這樣做是為了方便在子類中調(diào)用。注意其中的"Employee.superclass = Person.prototype;",這里是一個技巧,方便下面在子類中調(diào)用父類的方法。
          另一個需要注意的地方是"Employee.superclass.init.call(this, first, last);":對于所有對象中的方法來說,都可以通過兩個方法來調(diào)用--"call" 和 "apply".
          這里使用了call方法,其中第一個參數(shù)是將在調(diào)用的方法中訪問的對象,后面的參數(shù)與調(diào)用方法的參數(shù)一致。
           apply方法的使用與call大致一致,不同在于除了第一個參數(shù)外,后面是一個參數(shù)數(shù)組。

          下面附上完整的例子和類圖:

          繼承關(guān)系圖如下:
          o_javascriptOOP.gif

          代碼

          posted on 2006-03-06 19:40 zJun's帛羅閣 閱讀(3747) 評論(6)  編輯  收藏

          評論

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2006-03-06 22:06 dudu

          建議放在其他技術(shù)區(qū)!  回復(fù)  更多評論   

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2006-03-07 09:14 Haha

          很好!謝謝!  回復(fù)  更多評論   

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2006-03-24 18:40 查到這來了

          Person.prototype.toString() {
          return this.first + " " + this.last;
          }
          這里寫錯了!
          應(yīng)該是:
          Person.prototype.toString = function(){
          return this.first + " " + this.last;
          }  回復(fù)  更多評論   

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2006-05-24 18:35 student02370236

          在Javascript中this的含義和在JAVA中是不一樣的!!!
          在javascript中this是指向全局對象的...

          在O'REILLY的<JavaScript權(quán)威指南>一書中有如下的描述:
          In top-level code (i.e., JavaScript code that is not part of a function), you can use the JavaScript keyword this to refer to the global object. Within functions, this has a different use(Javascript Definitive Guide:Part 4.6.1)  回復(fù)  更多評論   

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2006-05-24 18:41 student02370236

          我看了本文的英文原版,我認(rèn)為他對這個this的描述有問題...  回復(fù)  更多評論   

          # re: 在javascript中實(shí)現(xiàn)繼承關(guān)系 2008-05-23 11:32 ss

          aaaaa  回復(fù)  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          <2006年3月>
          2627281234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          統(tǒng)計(jì)

          常用鏈接

          留言簿(15)

          隨筆分類

          隨筆檔案

          相冊

          收藏夾

          博客

          文檔

          站點(diǎn)

          論壇

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 探索| 称多县| 浦县| 宁武县| 汾西县| 甘泉县| 汝南县| 平遥县| 日喀则市| 江油市| 博野县| 乐都县| 德惠市| 盐津县| 乳源| 巨野县| 叶城县| 五常市| 蒙城县| 柏乡县| 同江市| 新乡市| 西丰县| 新昌县| 舞阳县| 黑龙江省| 库车县| 莎车县| 永昌县| 大埔县| 巢湖市| 静海县| 阿坝| 沙坪坝区| 雷波县| 光泽县| 潼关县| 惠水县| 松江区| 靖西县| 仁布县|