欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中實(shí)現(xiàn)繼承的三種方式和實(shí)例

 更新時(shí)間:2015年01月29日 09:37:18   投稿:junjie  
這篇文章主要介紹了JavaScript中實(shí)現(xiàn)繼承的三種方式和實(shí)例,本文講解了類式繼承、原型式繼承、使用擴(kuò)充方法實(shí)現(xiàn)多重繼承三種方式,需要的朋友可以參考下

javascript雖然是一門面向?qū)ο蟮恼Z言,但是它的繼承機(jī)制從一開始設(shè)計(jì)的時(shí)候就不同于傳統(tǒng)的其他面向?qū)ο笳Z言,是基于原型的繼承機(jī)制,但是在這種機(jī)制下,繼承依然有一些不同的實(shí)現(xiàn)方式。

方法一:類式繼承

所謂的類式繼承就是指模仿傳統(tǒng)面向?qū)ο笳Z言的繼承方式,繼承與被繼承的雙方都是“類”,代碼如下:

首先定義一個(gè)父類(或超類):

function Person(name){
    this.name=name;
  }

  Person.prototype.getName=function(){
    return this.name;
  };

該父類person的屬性在構(gòu)造函數(shù)中定義,可以保證繼承它的子類的name屬性不與它共享這個(gè)屬性,而是單獨(dú)屬于子類,將getName方法掛載到原型上,是為了讓繼承它的子類的多個(gè)實(shí)例共享這一個(gè)方法體,這樣能夠節(jié)省內(nèi)存,(對(duì)于多個(gè)實(shí)例來講,每次New一個(gè)實(shí)例出來都會(huì)保證這些實(shí)例的getName方法引用的是同一段內(nèi)存空間,而不是獨(dú)立的空間)。

定義一個(gè)繼承方法extend,如下:

function extend(subClass,superClass){
    var F=function(){};
    F.prototype=superClass.prototype;
    subClass.prototype=new F();
    subClass.prototype.constructor=subClass;

    subClass.superClass=superClass.prototype;
    if(superClass.prototype.constructor==Object.prototype.constructor){
      superClass.prototype.constructor=superClass;
    }

  }

在這個(gè)方法中,首先創(chuàng)建一個(gè)新的類為F,讓它的原型為父類的原型,并且讓子類的原型指向該類F的一個(gè)實(shí)例,從而達(dá)到了一個(gè)繼承父類的目的,同時(shí),子類的原型由于被修改,所以將修改后的原型的constructor屬性指向子類,讓其擁有構(gòu)造函數(shù),同時(shí)給該子類掛載一個(gè)superClass屬性,子類可以通過該屬性調(diào)用父類,從而建立起了子類和父類的關(guān)系。

定義一個(gè)子類Author來繼承父類Person,如下:

function Author(name,books){
    Author.superClass.constructor.call(this,name);
    this.book=books;
  }
  extend(Author,Person);
  Author.prototype.getBooks=function(){
    return this.book;
  }

這里在子類的構(gòu)造函數(shù)中通過其superClass屬性調(diào)用父類的構(gòu)造函數(shù),同時(shí)采用call方法,轉(zhuǎn)換該方法調(diào)用的this指向,讓子類Author也擁有(繼承)父類的屬性,同時(shí)子類又擁有自己的屬性book,所以在構(gòu)造函數(shù)中將參數(shù)books賦值給屬性book,達(dá)到構(gòu)造的目的。采用extend函數(shù)繼承父類Person原型上的屬性和方法(實(shí)際上只繼承了方法,因?yàn)槲覀冎爸皇菍⒎椒⊕燧d到了原型上,屬性是在構(gòu)造函數(shù)中定義的)。同時(shí),Author又擁有自己的方法getBooks,將其掛載到對(duì)應(yīng)的原型上,達(dá)到了在繼承的基礎(chǔ)上進(jìn)一步擴(kuò)充自身的目的。

這種繼承方式很明顯就是采用類似于傳統(tǒng)面向?qū)ο笳Z言的類式繼承,優(yōu)點(diǎn)是對(duì)習(xí)慣于傳統(tǒng)面向?qū)ο蟾拍畹某绦騿T來講很容易理解,缺點(diǎn)是過程比較繁瑣,內(nèi)存消耗稍大,因?yàn)樽宇愐矒碛凶约旱臉?gòu)造函數(shù)及原型,而且子類和父類的屬性完全是隔離的,即使兩者是一樣的值,但是不能共享同一段內(nèi)存。

方法二:原型式繼承

首先定義一個(gè)父類,這里不會(huì)刻意模仿使用構(gòu)造函數(shù)來定義,而是直接采用對(duì)象字面量的方式定義一個(gè)對(duì)象,該對(duì)象就是父類

var Person={
   name:'default name',
   getName:function(){
     return this.name;
   }

 } ;

和第一種方法一樣,該對(duì)象擁有一個(gè)屬性name和一個(gè)方法getName .

然后再定義一個(gè)克隆方法,用來實(shí)現(xiàn)子類對(duì)父類的繼承,如下:

function clone(obj){
     function F(){}
     F.prototype=obj;
     return new F();
   }

該克隆方法新建一個(gè)對(duì)象,將該對(duì)象的原型指向父類即參數(shù)obj,同時(shí)返回這個(gè)對(duì)象。

最后子類再通過克隆函數(shù)繼承父類,如下:

 var Author=clone(Person);
 Author.book=['javascript'];
 Author.showBook=function(){
 return this.book;
 }

這里定義一個(gè)子類,通過clone函數(shù)繼承父類Person,同時(shí)拓展了一個(gè)屬性book,和一個(gè)方法showBook,這里該子類也擁有屬性name,但是它和父類的name值是一樣的,所以沒有進(jìn)行覆蓋,如果不一樣,可以采用

 Author.name='new name';覆蓋這個(gè)屬性,從而得到子類的一個(gè)新的name屬性值。

這種原型式繼承相比于類式繼承更為簡(jiǎn)單自然,同時(shí)如果子類的屬性和父類屬性值相同,可以不進(jìn)行修改的話,那么它們兩者其實(shí)共享的是同一段內(nèi)存空間,如上面的name屬性,缺點(diǎn)是對(duì)于習(xí)慣了傳統(tǒng)面向?qū)ο蟮某绦騿T難以理解,如果兩者要進(jìn)行選擇的話,無疑是這種方式更為優(yōu)秀一些。

既然javascript中采用基于原型的方式來實(shí)現(xiàn)繼承,而且每個(gè)對(duì)象的原型只能指向某個(gè)特定的類的實(shí)例(不能指向多個(gè)實(shí)例),那么如何實(shí)現(xiàn)多重繼承(即讓一個(gè)類同時(shí)具有多個(gè)類的方法和屬性,而且本身內(nèi)部不自己定義這些方法和屬性)?

在javascript設(shè)計(jì)模式中給出了一種摻元類(mixin class)的方式:

首先定義一個(gè)摻元類,用來保存一些常用的方法和屬性,這些方法和屬性可以通過拓展的方式添加到任何其他類上,從而被添加類就具有了該類的某些方法和屬性,如果定義多個(gè)摻元類,同時(shí)添加給一個(gè)類,那么該類就是間接實(shí)現(xiàn)了“多重繼承”,基于這種思想,實(shí)現(xiàn)如下:

摻元類定義:

var Mixin=function(){};
  Mixin.prototype={
    serialize:function(){
      var output=[];
      for(key in this){
        output.push(key+":"+this[key]);
      }
      return output.join(',');
    }
  }

該摻元類具有一個(gè)serialize方法,用來遍歷其自身,輸出自身的屬性和屬性值,并且將他們以字符串形式返回,中間用逗號(hào)隔開。

定義一個(gè)擴(kuò)充方法,用來使某個(gè)類經(jīng)過擴(kuò)充之后具備摻元類的屬性或方法,如下:

function augment(receivingClass,givingClass){
    if(arguments[2]){
      for(var i= 2,len=arguments.length;i<len;i++){
        receivingClass.prototype[arguments[i]]=givingClass.prototype[arguments[i]];
      }
    }
    else
    {
      for(methodName in givingClass.prototype){
        if(!receivingClass.prototype[methodName]){
          receivingClass.prototype[methodName]=givingClass.prototype[methodName];
        }
      }

    }
 }

該方法默認(rèn)是兩個(gè)參數(shù),第一個(gè)參數(shù)是接受被擴(kuò)充的類,第二個(gè)參數(shù)是摻元類(用來擴(kuò)充其他類的類),還可以有其他參數(shù),如果大于兩個(gè)參數(shù),后面的參數(shù)都是方法或者屬性名,用來表示被擴(kuò)充類只想繼承摻元類的指定的屬性或方法,否則默認(rèn)繼承摻元類的所有屬性和方法,在該函數(shù)中,第一個(gè)if分支是用來繼承指定屬性和方法的情形,else分支是默認(rèn)繼承所有屬性和方法的情形。該方法的實(shí)質(zhì)是將摻元類的原型上的屬性和方法都擴(kuò)充(添加)到了被擴(kuò)充類的原型上面,從而使其具有摻元類的屬性和方法。

最后,使用擴(kuò)充方法實(shí)現(xiàn)多重繼承

augment(Author,Mixin);
   var author= new Author('js',['javascript design patterns']);
   alert(author.serialize());

這里定義了一個(gè)author的類,該類繼承自Person父類,同時(shí)又具備摻元類Mixin的方法和屬性,如果你愿意,可以定義N個(gè)摻元類用來擴(kuò)充該類,它同樣能夠繼承你定義的其他摻元類的屬性和方法,這樣就實(shí)現(xiàn)了多重繼承,最后,author的serialize方法的運(yùn)行結(jié)果如下:

你會(huì)發(fā)現(xiàn)該類同時(shí)具有person類,Author類,Mixin類的屬性和方法,其中Person和Mixin的屬性和方法都是通過“繼承”得來的,從實(shí)際上來講,它實(shí)現(xiàn)了多重繼承。

相關(guān)文章

  • JavaScript中使用stopPropagation函數(shù)停止事件傳播例子

    JavaScript中使用stopPropagation函數(shù)停止事件傳播例子

    這篇文章主要介紹了JavaScript中使用stopPropagation函數(shù)停止事件傳播例子,即阻止事件冒泡的一個(gè)方法,需要的朋友可以參考下
    2014-08-08
  • JS?中的?Event?Loop?是什么你真的懂

    JS?中的?Event?Loop?是什么你真的懂

    Event Loop,簡(jiǎn)單翻譯就是?事件循環(huán),是 JS 語言下實(shí)現(xiàn)運(yùn)行時(shí)的一個(gè)機(jī)制,這篇文章主要介紹了JS?中的?Event?Loop?的基本知識(shí),需要的朋友可以參考下
    2022-06-06
  • js獲取內(nèi)聯(lián)樣式的方法

    js獲取內(nèi)聯(lián)樣式的方法

    這篇文章主要介紹了js獲取內(nèi)聯(lián)樣式的方法,針對(duì)標(biāo)準(zhǔn)瀏覽器與IE瀏覽器進(jìn)行不同的判斷與獲取,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • JavaScript實(shí)現(xiàn)圖片瀑布流和底部刷新

    JavaScript實(shí)現(xiàn)圖片瀑布流和底部刷新

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)圖片瀑布流和底部刷新,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • JavaScript變量聲明詳解

    JavaScript變量聲明詳解

    本文詳細(xì)向大家介紹了javascript變量聲明,并通過示例進(jìn)行了具體分析,是篇非常不錯(cuò)的文章,這里推薦給剛?cè)腴T的jser。
    2014-11-11
  • javascript 網(wǎng)站常用的iframe分割

    javascript 網(wǎng)站常用的iframe分割

    就是一個(gè)頁面使用兩個(gè)iframe來調(diào)用內(nèi)容,實(shí)現(xiàn)頁面導(dǎo)航,更容易控制,可控制性好
    2008-06-06
  • JavaScript中常用的3種彈出提示框(alert、confirm、prompt)

    JavaScript中常用的3種彈出提示框(alert、confirm、prompt)

    這篇文章主要給大家介紹了關(guān)于JavaScript中常用的3種彈出提示框(alert、confirm、prompt)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • JavaScript flash復(fù)制庫類 Zero Clipboard

    JavaScript flash復(fù)制庫類 Zero Clipboard

    開發(fā)中經(jīng)常會(huì)用到復(fù)制的功能,在 IE 下實(shí)現(xiàn)比較簡(jiǎn)單。但要想做到跨瀏覽器比較困難了。
    2011-01-01
  • js簡(jiǎn)單實(shí)現(xiàn)圖片延遲加載的方法

    js簡(jiǎn)單實(shí)現(xiàn)圖片延遲加載的方法

    這篇文章主要介紹了js簡(jiǎn)單實(shí)現(xiàn)圖片延遲加載的方法,涉及javascript針對(duì)頁面元素的遍歷與動(dòng)態(tài)設(shè)置技巧,需要的朋友可以參考下
    2016-07-07
  • 用js的document.write輸出的廣告無阻塞加載的方法

    用js的document.write輸出的廣告無阻塞加載的方法

    這篇文章主要介紹了用js的document.write輸出的廣告無阻塞加載的方法,需要的朋友可以參考下
    2014-06-06

最新評(píng)論