JS繼承

JS中的繼承

許多OO語言都支持兩種繼承方式:接口繼承和實現(xiàn)繼承;

因為JS中沒有類和接口的概念 , 所以JS不支持接口繼承 , 只支持實現(xiàn)繼承;

實現(xiàn)繼承主要是依靠原型鏈來實現(xiàn)的;

1.原型鏈

基本思想:

利用原型讓一個對象繼承另一個對象的屬性和方法 ;

回顧構(gòu)造函數(shù),原型和實例的關(guān)系 :

每個構(gòu)造函數(shù)都有一個原型對象 ; 原型對象都包含一個指向構(gòu)造函數(shù)的指針 , 而實例包含一個指向原型 ;

   function Person(name,age) {
       this.name = name;
       this.age = age;
   }
   Person.prototype.speakName = function () {
       console.log(this.name)
   }
   
   var p1 = new Person("老王",25);
   var p2 = new Person("小王",15);

那假如我們把一個實例對象,作為另外一個實例的原型對象會發(fā)生什么呢?

      //定義一個構(gòu)造函數(shù)翘盖。
    function Father () {
        // 添加name屬性.  默認直接賦值了谊囚。當(dāng)然也可以通過構(gòu)造函數(shù)傳遞過來
        this.name = "馬云";
    }
      //給Father的原型添加giveMoney方法
    Father.prototype.giveMoney = function () {
        alert("我是Father原型中定義的方法");
    }
    //再定義一個構(gòu)造函數(shù)涎永。
    function Son () {
        //添加age屬性
        this.age = 18;
    }
    //關(guān)鍵地方:把Son構(gòu)造方法的原型替換成Father的對象迷殿。  因為原型是對象,任何對象都可以作為原型
    Son.prototype = new Father();
      //給Son的原型添加getMoney方法
    Son.prototype.getMoney = function () {
        alert("我是Son的原型中定義的方法");
    }
    //創(chuàng)建Son類型的對象
    var son1 = new Son();

    //發(fā)現(xiàn)不僅可以訪問Son中定義屬性和Son原型中定義的方法,也可以訪問Father中定義的屬性和Father原型中的方法。
    //這樣就通過原型完成了類型之間的繼承。 
    // Son繼承了Father中的屬性和方法励七,當(dāng)然還有Father原型中的屬性和方法智袭。
    son1.giveMoney();
    son1.getMoney();
    alert("Father定義的屬性:" + son1.name);
    alert("Son中定義的屬性:" + son1.age);
  1. 定義Son構(gòu)造函數(shù)后,我們沒有再使用Son的默認原型掠抬,而是把他的默認原型更換成了Father類型對象吼野。
  2. 這時,如果這樣訪問 son1.name, 則先在son1中查找name屬性两波,沒有然后去他的原型( Father對象)中找到了瞳步,所以是"馬云"闷哆。
  3. 如果這樣訪問 son1.giveMoney(), 先在son1中找這個方法,找不到去他的原型中找单起,仍然找不到抱怔,則再去這個原型的原型中去找,然后在 Father的原型對象中 找到了嘀倒。
  4. 從圖中可以看出來屈留,在訪問屬性和方法的時候,查找的順序是這樣的:對象->原型->原型的原型->...->原型鏈的頂端测蘑。 就像一個鏈條一樣灌危,這樣 由原型連成的"鏈條",就是我們經(jīng)常所說的原型鏈碳胳。
  5. 從上面的分析可以看出勇蝙,通過原型鏈的形式就完成了JavaScript的繼承。

2.默認原型鏈

原型鏈的頂端一定是Object這個構(gòu)造函數(shù)的原型對象挨约。

3. 測試數(shù)據(jù)類型

isPrototypeOf( 對象 ) : 這是個 原型對象 的方法味混,參數(shù)傳入一個對象,判斷參數(shù)對象是不是由這個原型派生出來的烫罩。 也就是判斷這個原型是不是參數(shù)對象原型鏈中的一環(huán)惜傲。

4.原型鏈的缺陷

父類型的構(gòu)造函數(shù)創(chuàng)建的對象,會成為子類型的原型

缺陷:

  1. 父類型中定義的實例屬性 , 會成為子類型的原型屬性 ; 子類型原型中的屬性被所有的子類型的實例所共用;(屬性共用)
  2. 原型鏈繼承中,只有一個地方用到了父類型的構(gòu)造函數(shù) , 也就意味著只有一次傳遞參數(shù)的機會 , 并且參數(shù)的值在所有的子類實例里都是一樣的;(參數(shù)傳遞困難)

5.借用構(gòu)造函數(shù)彌補缺陷

如何借用?

? 使用call或apply完成==構(gòu)造函數(shù)的借調(diào)== ,目的在于借用父類型(或其他類型)的構(gòu)造函數(shù) , 完成子類型的屬性添加 ;

原理

? call和apply 可以更改 構(gòu)造方法內(nèi)部的 this 指向指定的對象上;

    function Father (name,age) {
        this.name = name;
        this.age = age;
    }
    //如果這樣直接調(diào)用,那么father中的this只的是 window贝攒。 因為其實這樣調(diào)用的: window.father("李四", 20)
    // name 和age 屬性就添加到了window屬性上
    Father("李四", 20);
    alert("name:" + window.name + "\nage:" + window.age);  //可以正確的輸出

    //使用call方法調(diào)用盗誊,則可以改變this的指向
    function Son (name, age, sex) {
        this.sex = sex;
          //調(diào)用Father方法(看成普通方法),第一個參數(shù)傳入一個對象this隘弊,則this(Son類型的對象)就成為了Father中的this
        Father.call(this, name, age);
    }
    var son = new Son("張三", 30, "男");
    alert("name:" + son.name + "\nage:" + son.age + "\nsex:" + son.sex);
      alert(son instanceof Father); //false

注意

? 在這里并不是真正的繼承 , 借用的構(gòu)造函數(shù)在這里也只是作為一個普通的方法;

缺陷

? 單獨使用借用時 ; 父類型原型對象中的共享屬性和方法 ; 通過借用無法獲取 ;

6. 組合繼承

組合函數(shù)利用了原型繼承和構(gòu)造函數(shù)借調(diào)繼承的優(yōu)點哈踱,組合在一起。成為了使用最廣泛的一種繼承方式梨熙。

      //定義父類型的構(gòu)造函數(shù)
    function Father (name,age) {
        // 屬性放在構(gòu)造函數(shù)內(nèi)部
        this.name = name;
        this.age = age;
        // 方法定義在原型中
        if((typeof Father.prototype.eat) != "function"){
            Father.prototype.eat = function () {
                alert(this.name + " 在吃東西");
            }
        }  
    }
      // 定義子類類型的構(gòu)造函數(shù)
    function Son(name, age, sex){
          //借調(diào)父類型的構(gòu)造函數(shù)开镣,相當(dāng)于把父類型中的屬性添加到了未來的子類型的對象中
        Father.call(this, name, age);
        this.sex = sex;
    }
      //修改子類型的原型為父類型的對象。這樣就可以繼承父類型中的方法了咽扇。
    Son.prototype = new Father(    );
    var son1 = new Son("志玲", 30, "女");
    alert(son1.name);
    alert(son1.sex);
    alert(son1.age);
    son1.eat();

總結(jié)

共同的方法和屬性通過原型鏈繼承 ;

需要傳入?yún)?shù)的屬性(子類型實例中的不相同屬性)通過 call或apply的方法 借調(diào)一個 構(gòu)造函數(shù)來完成屬性的添加 (子類屬性中的同名屬性會覆蓋掉原型中的屬性);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邪财,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子质欲,更是在濱河造成了極大的恐慌树埠,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘶伟,死亡現(xiàn)場離奇詭異怎憋,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門绊袋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毕匀,“玉大人,你說我怎么就攤上這事癌别≡聿恚” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵规个,是天一觀的道長凤薛。 經(jīng)常有香客問我,道長诞仓,這世上最難降的妖魔是什么缤苫? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮墅拭,結(jié)果婚禮上活玲,老公的妹妹穿的比我還像新娘。我一直安慰自己谍婉,他們只是感情好舒憾,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著穗熬,像睡著了一般镀迂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唤蔗,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天探遵,我揣著相機與錄音,去河邊找鬼妓柜。 笑死箱季,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棍掐。 我是一名探鬼主播藏雏,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼作煌!你這毒婦竟也來了掘殴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤粟誓,失蹤者是張志新(化名)和其女友劉穎奏寨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體努酸,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年杜恰,在試婚紗的時候發(fā)現(xiàn)自己被綠了获诈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仍源。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖舔涎,靈堂內(nèi)的尸體忽然破棺而出笼踩,到底是詐尸還是另有隱情,我是刑警寧澤亡嫌,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布嚎于,位于F島的核電站,受9級特大地震影響挟冠,放射性物質(zhì)發(fā)生泄漏于购。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一知染、第九天 我趴在偏房一處隱蔽的房頂上張望肋僧。 院中可真熱鬧,春花似錦控淡、人聲如沸嫌吠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辫诅。三九已至,卻和暖如春涧狮,著一層夾襖步出監(jiān)牢的瞬間炕矮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工勋篓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吧享,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓譬嚣,卻偏偏與公主長得像钢颂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拜银,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 原文鏈接 js的繼承有6種方式殊鞭,大致總結(jié)一下它們各自的優(yōu)缺點,以及它們之間的關(guān)系尼桶。 1.原型鏈 js的繼承機制不同...
    空_城__閱讀 791評論 0 11
  • 原型鏈 繼承是通過創(chuàng)建SuperType的實例操灿,并將該實例賦給SubType.prototype實現(xiàn)的。繼承的本質(zhì)...
    大橙子CZ閱讀 491評論 0 1
  • 時間:2017.9.12 形式:線下 議題:工作要不要繼續(xù)泵督,想回老家發(fā)展趾盐。 背景介紹:案主目前在青島工作,男朋友在...
    宓兒_2b3e閱讀 202評論 0 1
  • 今天從早上十點(俺們這嘎達冬天是北京時間十點上班)出門,和一幫同事~下農(nóng)村~一直到21點多回來救鲤,被同事叫去吃了碗面...
    至簡從心閱讀 799評論 10 19
  • 最近久窟,看到了一個超腦的問答:一男子想追求喜歡的女神,但不知該如何表達本缠,于是去找情感咨詢師尋問斥扛,男子說“我喜歡女神很...
    漏斗中柱閱讀 262評論 0 0