繼承

繼承

許多OO語言都支持兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承占键。接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法尉辑。由于函數(shù)沒有簽名鸠补,在ECMAScript中無法實(shí)現(xiàn)接口繼承萝风,ECMAScript只支持實(shí)現(xiàn)繼承,而且其實(shí)實(shí)現(xiàn)繼承的主要是依靠原型鏈來實(shí)現(xiàn)的紫岩。

一、原型鏈

基本思想是利用原型讓一個(gè)引用型繼承另一個(gè)引用類型的屬性和方法睬塌。

構(gòu)造函數(shù)泉蝌、原型和實(shí)例的關(guān)系:

每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對象歇万,原型對象包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例包含一個(gè)指向原型對象的內(nèi)部指針勋陪。

      // 構(gòu)造函數(shù) SuperType
      function SuperType() {
        this.property = true;
      }

      SuperType.prototype.getSuperValue = function () {
        return this.property;
      };

      // 構(gòu)造函數(shù) SubType
      function SubType() {
        this.subproperty = false;
      }

      // 繼承了 SuperType
      SubType.prototype = new SuperType();

      SubType.prototype.getSubValue = function () {
        return this.subproperty;
      };

      var instance = new SubType();
      alert(instance.getSuperValue());

那么贪磺,讓原型對象等于另一個(gè)類型的實(shí)例,此時(shí)的原型對象將包含一個(gè)指向另一個(gè)原型的指針诅愚,相應(yīng)地寒锚,另一個(gè)原型中也包含一個(gè)指向另一個(gè)原型的指針。假如另一個(gè)原型又是另一個(gè)原型的實(shí)例违孝,那么上述關(guān)系依然成立刹前,如此層層遞進(jìn),就構(gòu)成了實(shí)例與原型的鏈條雌桑。這就是所謂原型鏈的基本概念喇喉。

  1. 確定原型和實(shí)例的關(guān)系

    a. instanceof

    b. isPrototypeOf()

  2. 原型鏈的問題

    在通過原型來實(shí)現(xiàn)繼承時(shí),原型實(shí)際上會變成另一個(gè)類型的實(shí)例校坑。于是拣技,原先的實(shí)例屬性也就順理成章地變成了現(xiàn)在的原型屬性。

      function SuperType() {
        this.colors = ["red", "blue", "green"];
      }

      function SubType() {}

      SubType.prototype = new SuperType();

      var instance1 = new SubType();
      instance1.colors.push("black");
      alert(instance1.colors); //"red,blue,green,black"

      var instance2 = new SubType();
      alert(instance2.colors); //"red,blue,green,black"

3.1.SubType通過原型鏈繼承了SuperType之后耍目,SubType.protype就變成了SubperType的一個(gè)實(shí)例膏斤,因此它也擁有了一個(gè)它自己的colors屬性,就跟專門創(chuàng)建了一個(gè)SubType.prototype.colors屬性一樣邪驮。結(jié)果SubType的所有實(shí)例都會共享這一個(gè)colors屬性莫辨。

3.2 創(chuàng)建子類型的實(shí)例時(shí),不能想超類型的構(gòu)造函數(shù)傳遞參數(shù)耕捞。不能在不影響所有對象類型的情況下衔掸,給超類型的構(gòu)造函數(shù)傳遞參數(shù)。

二俺抽、借用構(gòu)造函數(shù)

這種也稱為偽造對象或經(jīng)典繼承敞映,即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)。

      function SuperType() {
        this.colors = ["red", "blue", "green"];
      }

      function SubType() {
        SuperType.call(this);
      }

      var instance1 = new SubType();
      instance1.colors.push("black");
      alert(instance1.colors); // "red,blue,green,black"

      var instance2 = new SubType();
      alert(instance2.colors); //"red,blue,green"

2.1 傳遞參數(shù)

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

      function SubType() {
        SuperType.call(this, "Nicholas");

        this.age = 29;
      }

      var instance = new SubType();
      alert(instance.name);
      alert(instance.age);

2.2 構(gòu)造函數(shù)的問題

方法都在構(gòu)造函數(shù)中定義磷斧,無法做到函數(shù)復(fù)用

三振愿、組合繼承

組合繼承,有時(shí)候也叫做偽經(jīng)典繼承弛饭,指的是將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一塊冕末,從而發(fā)揮二者之長的一種繼承模式。思路是使用原型鏈實(shí)現(xiàn)對原型屬性和方法的繼承侣颂,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對實(shí)例屬性的繼承档桃。

      function SuperType(name) {
        this.name = name;
        this.colors = ["red", "blue", "green"];
      }
      SuperType.prototype.sayName = function () {
        alert(this.name);
      };
      function SubType(name, age) {
        SuperType.call(this, name);

        this.age = age;
      }

      // 繼承方法
      SubType.prototype = new SuperType();

      SubType.prototype.sayAge = function () {
        alert(this.age);
      };

      var instance1 = new SubType("Nicholas", 29);
      instance1.colors.push("black");
      alert(instance1.colors); //"red,blue,green,black"
      instance1.sayName(); //"Nicholas"
      instance1.sayAge(); //29

      var instance2 = new SubType("Greg", 27);
      alert(instance2.colors); //"red,blue,green"
      instance2.sayName(); //"Greg"
      instance2.sayAge(); //27

組合繼承是最常用的繼承模式。

四憔晒、原型式繼承

借助已有的對象創(chuàng)建新對象藻肄,同時(shí)還不必因此創(chuàng)建自定義類型蔑舞。

      function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
      }

      var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"],
      };

      var anotherPerson = object(person);
      anotherPerson.name = "Greg";
      anotherPerson.friends.push("Rob");

      var yetAnotherPerson = object(person);
      yetAnotherPerson.name = "Linda";
      yetAnotherPerson.friends.push("Barbie");

      alert(person.friends);

ECMAScript5通過新增Object.create()方法規(guī)范化了原型式繼承。這個(gè)方法接收兩個(gè)參數(shù):一個(gè)用作新對象原型的對象和一個(gè)為新對象定義額外屬性的對象嘹屯。

      var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"],
      };

      var anotherPerson = Object.create(person);
      anotherPerson.name = "Greg";
      anotherPerson.friends.push("Rob");

      var yetAnotherPerson = Object.create(person);
      yetAnotherPerson.name = "Linda";
      yetAnotherPerson.friends.push("Barbie");

      alert(person.friends);

五攻询、寄生式繼承

寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個(gè)僅用于封裝繼承過程的函數(shù)州弟,該函數(shù)在內(nèi)部以某種方式來增強(qiáng)對象钧栖,最后再像真地是它做了所有工作一樣返回對象。

      function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
      }
      function createAnother(original) {
        var clone = Object(original);
        clone.sayHi = function () {
          alert("Hi");
        };
        return clone;
      }
      var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"],
      };

      var anotherPerson = createAnother(person);
      anotherPerson.sayHi();

不能做到函數(shù)復(fù)用婆翔;

六拯杠、寄生組合繼承

組合繼承最大問題是無論什么情況下,都會調(diào)用兩次超類型構(gòu)造函數(shù):一次是創(chuàng)建子類型的時(shí)候浙滤,另一次是在子類型構(gòu)造函數(shù)內(nèi)部阴挣。

      function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
      }
      function inheritPrototype(subType, superType) {
        // 創(chuàng)建對象
        var prototype = object(superType.prototype);
        // 增強(qiáng)對象
        prototype.constructor = subType;
        // 指定對象
        subType.prototype = prototype;
      }

      function SuperType(name) {
        this.name = name;
        this.colors = ["red", "blue", "green"];
      }

      SuperType.prototype.sayName = function () {
        alert(this.name);
      };
      function SubType(name, age) {
        SuperType.call(this, name);

        this.age = age;
      }

      inheritPrototype(SubType, SuperType);

      SubType.prototype.sayAge = function () {
        alert(this.age);
      };

只調(diào)用了一次SuperType構(gòu)造函數(shù),最理想的繼承方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纺腊,一起剝皮案震驚了整個(gè)濱河市畔咧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌揖膜,老刑警劉巖誓沸,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異壹粟,居然都是意外死亡拜隧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門趁仙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洪添,“玉大人,你說我怎么就攤上這事雀费「缮荩” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵盏袄,是天一觀的道長忿峻。 經(jīng)常有香客問我,道長辕羽,這世上最難降的妖魔是什么逛尚? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刁愿,結(jié)果婚禮上绰寞,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好克握,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布蕾管。 她就那樣靜靜地躺著枷踏,像睡著了一般菩暗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旭蠕,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天停团,我揣著相機(jī)與錄音,去河邊找鬼掏熬。 笑死佑稠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旗芬。 我是一名探鬼主播舌胶,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疮丛!你這毒婦竟也來了幔嫂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤誊薄,失蹤者是張志新(化名)和其女友劉穎履恩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呢蔫,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡切心,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了片吊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绽昏。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖俏脊,靈堂內(nèi)的尸體忽然破棺而出全谤,到底是詐尸還是另有隱情,我是刑警寧澤联予,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布啼县,位于F島的核電站,受9級特大地震影響沸久,放射性物質(zhì)發(fā)生泄漏季眷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一卷胯、第九天 我趴在偏房一處隱蔽的房頂上張望子刮。 院中可真熱鬧,春花似錦、人聲如沸挺峡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橱赠。三九已至尤仍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狭姨,已是汗流浹背宰啦。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饼拍,地道東北人赡模。 一個(gè)月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像师抄,于是被迫代替她去往敵國和親漓柑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

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

  • 繼承是 OO 語言中的一個(gè)最為人津津樂道的概念叨吮。許多 OO 語言都支持兩種繼承方式:接口繼承 和 實(shí)現(xiàn)繼承辆布。接口繼...
    threetowns閱讀 447評論 0 0
  • 1.繼承(接口繼承和實(shí)現(xiàn)繼承) 繼承是 OO 語言中的一個(gè)最為人津津樂道的概念。許多 OO 語言都支持兩種繼承方式...
    believedream閱讀 955評論 0 3
  • 一挤安、原型鏈 學(xué)過java的同學(xué)應(yīng)該都知道谚殊,繼承是java的重要特點(diǎn)之一,許多面向?qū)ο蟮恼Z言都支持兩種繼承方式:接口...
    grain先森閱讀 1,422評論 0 39
  • 內(nèi)容來自《JavaScript高級程序設(shè)計(jì)》第三版第6章第3節(jié) 原型鏈 ECMAScript中描述了 原型鏈的概念...
    angelwgh閱讀 238評論 0 0
  • 1蛤铜、構(gòu)造函數(shù)模式 [url=]file:///C:/Users/i037145/AppData/Local/Tem...
    橫沖直撞666閱讀 855評論 0 0