前端js復(fù)習(xí) 7-繼承

孩兒們棺滞,來繼承為父的遺產(chǎn)吧,咳咳咳咳矢渊。開個玩笑继准。繼承理解為取存在對象已有屬性和方法的一種方式.,那么我們有幾種方式可以實現(xiàn)呢矮男。接下來請開始個人showtime移必。

  • 1.原型鏈繼承

原理:我們都知道在實例中查找該屬性,如果找到了毡鉴,返回該值崔泵,否則,通過__proto__找到原型對象猪瞬,在原型對象中進行搜索憎瘸,如果找到,返回該值陈瘦,否則幌甘,繼續(xù)向上進行搜索,直到找到該屬性,或者在原型鏈中沒有找到锅风,返回undefined酥诽。

function Parent() {
    this.name = '爸爸';
    this.family = ['媽媽','哥哥'] //驗證引用類型的屬性會被所有實例共享
}
Parent.prototype.getName = function() {
   console.log(this.name)
   console.log(this.family )
}
function Child() {}
Child.prototype = new Parent();

var child = new Child();
child.getName() // '爸爸'  ["媽媽", "哥哥"]
child.family.push('姐姐')
var child2 = new Child();
child2.getName() // '爸爸' ["媽媽", "哥哥", "姐姐"]

給你們畫個靈魂圖你們就知道了為啥是這樣的結(jié)果 --。--


image.png

缺點: 引用類型的屬性會被所有實例共享,在創(chuàng)建Child實例時不能想Parent傳參

  • 2 借用構(gòu)造函數(shù)(經(jīng)典 經(jīng)典 經(jīng)典 重要的事情說三遍)
function Parent (name) {
  this.name = name;
  this.family = ['媽媽','哥哥']
  this.getName = function() {
      console.log(this.name)
      console.log(this.family)
  }
}
function Child(name) {
   Parent.call(this,name) //重點是這個哦
}
var child = new Child(爸爸)
child.getName() // '爸爸'  ["媽媽", "哥哥"]
child.family.push('姐姐')
var child2 = new Child('我');
child2.getName()  // '我'  ["媽媽", "哥哥"]

我們明顯的可以看到了與上一個相比避免了引用類型的屬性被所有實例共享皱埠,而且我們還可以從Child中向Parent傳參哦

  • 3 組合繼承(雙劍合并來了)
function Parent(name) {
     this.name = name;
     this.family = ['媽媽','哥哥']
}
Parent.prototype.getName = function () {
      console.log(this.name)
      console.log(this.family)
}
function Child(name) {
   Parent.call(this,name)
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('我');
child1.family.push('爸爸');
child1.getName(); // 我 ["媽媽", "哥哥", "爸爸"]
var child2 = new Child('你')
child2.getName(); // 你 ["媽媽", "哥哥"]
console.log(Child.prototype.constructor)

優(yōu)點怎么說肮帐,集兩家之長吧,是JavaScript中最常用的繼承模式(ps:你覺得到這就可以了吧边器,呵呵训枢,你還太年輕了往下看)。

  • 4原型式繼承 (不是原型鏈繼承哦)
function createObj(o) {
  function F(){};
  F.prototype= o;
  return  new F();
}

var parent = {
   name : '我',
   family : ['媽媽','哥哥']
}
var child1 = createObj(parent);
var child2 = createObj(parent);
console.log(child1.name); // 我
child1.name = "你";
console.log(child2.name);  // 我 
// 注意這里并不是因為child1和child2有獨立的name值饰抒,而是因為child1.name直接給
// child1添加了屬性肮砾,并沒有去影響原型上的name值

console.log(child1.family ); //["媽媽", "哥哥"]
child1.family.push('爸爸');
console.log(child2.family ); //  ["媽媽", "哥哥", "爸爸"]

簡單理解就是把傳入的對象變成了創(chuàng)建對象的原型,然后返回這個對象袋坑,就類似與我把對象的prototype寫成了一個參數(shù)仗处。

  • 5 寄生組合式繼承 -------------------------快瘋了--------------------------
    創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種方式增強對象(給對象添加屬性和方法), 然后返回該對象
function createObj(o) {
    var clone = Object.create(o);
    clone.say = function () {
        console.log('我是新增的方法咯')
    }
    return clone;
}

有木有感覺和原型式繼承差不多枣宫,不過上一個是修改創(chuàng)建對象的原型婆誓,這個是直接修改對象的屬性和方法。
缺點: 每次創(chuàng)建對象都會創(chuàng)建一遍方法

  • 6 寄生組合式繼承
    我們重顧一下
    孩兒們也颤,來繼承為父的遺產(chǎn)吧洋幻,咳咳咳咳。開個玩笑翅娶。繼承理解為取存在對象已有屬性和方法的一種方式.文留,那么我們有幾種方式可以實現(xiàn)呢。接下來請開始個人showtime竭沫。

  • 1.原型鏈繼承

原理:我們都知道在實例中查找該屬性燥翅,如果找到了,返回該值蜕提,否則森书,通過__proto__找到原型對象,在原型對象中進行搜索谎势,如果找到凛膏,返回該值,否則脏榆,繼續(xù)向上進行搜索猖毫,直到找到該屬性,或者在原型鏈中沒有找到须喂,返回undefined吁断。

function Parent() {
    this.name = '爸爸';
    this.family = ['媽媽','哥哥'] //驗證引用類型的屬性會被所有實例共享
}
Parent.prototype.getName = function() {
   console.log(this.name)
   console.log(this.family )
}
function Child() {}
Child.prototype = new Parent();

var child = new Child();
child.getName() // '爸爸'  ["媽媽", "哥哥"]
child.family.push('姐姐')
var child2 = new Child();
child2.getName() // '爸爸' ["媽媽", "哥哥", "姐姐"]

給你們畫個靈魂圖你們就知道了為啥是這樣的結(jié)果 --典唇。--


image.png

缺點: 引用類型的屬性會被所有實例共享,在創(chuàng)建Child實例時不能想Parent傳參

  • 2 借用構(gòu)造函數(shù)(經(jīng)典 經(jīng)典 經(jīng)典 重要的事情說三遍)
function Parent (name) {
  this.name = name;
  this.family = ['媽媽','哥哥']
  this.getName = function() {
      console.log(this.name)
      console.log(this.family)
  }
}
function Child(name) {
   Parent.call(this,name) //重點是這個哦
}
var child = new Child(爸爸)
child.getName() // '爸爸'  ["媽媽", "哥哥"]
child.family.push('姐姐')
var child2 = new Child('我');
child2.getName()  // '我'  ["媽媽", "哥哥"]

我們明顯的可以看到了與上一個相比避免了引用類型的屬性被所有實例共享,而且我們還可以從Child中向Parent傳參哦

  • 3 組合繼承(雙劍合并來了)
function Parent(name) {
     this.name = name;
     this.family = ['媽媽','哥哥']
}
Parent.prototype.getName = function () {
      console.log(this.name)
      console.log(this.family)
}
function Child(name) {
   Parent.call(this,name)
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('我');
child1.family.push('爸爸');
child1.getName(); // 我 ["媽媽", "哥哥", "爸爸"]
var child2 = new Child('你')
child2.getName(); // 你 ["媽媽", "哥哥"]
console.log(Child.prototype.constructor)

優(yōu)點怎么說胯府,集兩家之長吧,是JavaScript中最常用的繼承模式(ps:你覺得到這就可以了吧恨胚,呵呵骂因,你還太年輕了往下看)。

  • 4原型式繼承 (不是原型鏈繼承哦)
function createObj(o) {
  function F(){};
  F.prototype= o;
  return  new F();
}

var parent = {
   name : '我',
   family : ['媽媽','哥哥']
}
var child1 = createObj(parent);
var child2 = createObj(parent);
console.log(child1.name); // 我
child1.name = "你";
console.log(child2.name);  // 我 
// 注意這里并不是因為child1和child2有獨立的name值赃泡,而是因為child1.name直接給
// child1添加了屬性寒波,并沒有去影響原型上的name值

console.log(child1.family ); //["媽媽", "哥哥"]
child1.family.push('爸爸');
console.log(child2.family ); //  ["媽媽", "哥哥", "爸爸"]

簡單理解就是把傳入的對象變成了創(chuàng)建對象的原型,然后返回這個對象升熊,就類似與我把對象的prototype寫成了一個參數(shù)俄烁。

  • 5 寄生組合式繼承 -------------------------快瘋了--------------------------
    創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種方式增強對象(給對象添加屬性和方法), 然后返回該對象
function createObj(o) {
    var clone = Object.create(o);
    clone.say = function () {
        console.log('我是新增的方法咯')
    }
    return clone;
}

有木有感覺和原型式繼承差不多级野,不過上一個是修改創(chuàng)建對象的原型页屠,這個是直接修改對象的屬性和方法。
缺點: 每次創(chuàng)建對象都會創(chuàng)建一遍方法

  • 6 寄生組合式繼承
    我們重顧一下
function Parent(name) {
     this.name = name;
     this.family = ['媽媽','哥哥']
}
Parent.prototype.getName = function () {
      console.log(this.name)
      console.log(this.family)
}
function Child(name) {
   Parent.call(this,name)
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('我');
child1.family.push('爸爸');
child1.getName(); // 我 ["媽媽", "哥哥", "爸爸"]
var child2 = new Child('你')
child2.getName(); // 你 ["媽媽", "哥哥"]
console.log(Child.prototype.constructor)

發(fā)現(xiàn)我們會調(diào)用兩次父構(gòu)造函數(shù)蓖柔。
一次是設(shè)置子類型實例原型的時候
Child.prototype = new Parent();
一次是創(chuàng)建子類型實例的時候
var child1 = new Child('我');
而其在這里我們也會調(diào)用一次Parent構(gòu)造含糊
Parent.call(this,name)

那么我們怎么避免重復(fù)調(diào)用呢辰企?加入我們是間接的讓Child.prototype 訪問到Parent.prototype呢

function Parent(name) {
     this.name = name;
     this.family = ['媽媽','哥哥']
}
Parent.prototype.getName = function () {
      console.log(this.name)
      console.log(this.family)
}
function Child(name) {
   Parent.call(this,name)
}
// 關(guān)鍵在這
var F = function() {}
F.prototype = Parent.prototype;
child.protype = new F();

var child1 = nwe Child('我')
console.log(child)

這樣是不是減少了一次調(diào)用父構(gòu)造函數(shù)new Parent()

來我們封裝一下這個繼承方法

function object(o) {
    function F() {};
    F.prototype = o;
    return new F();
}
function prototype(child,parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}
prototype(Child,Parent);

而其還避免了在Parent.prototype上面創(chuàng)建不必要的多余的屬性,于此同時况鸣,原型鏈還能保持不變牢贸。開發(fā)人員普遍認為寄生式組合式繼承是引用類型最理想的繼承范式。

有沒有搞的頭昏镐捧,最后一個潜索,多看幾遍 哈哈哈哈

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懂酱,隨后出現(xiàn)的幾起案子竹习,更是在濱河造成了極大的恐慌,老刑警劉巖玩焰,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件由驹,死亡現(xiàn)場離奇詭異,居然都是意外死亡昔园,警方通過查閱死者的電腦和手機蔓榄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來默刚,“玉大人甥郑,你說我怎么就攤上這事』缥鳎” “怎么了澜搅?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵伍俘,是天一觀的道長。 經(jīng)常有香客問我勉躺,道長癌瘾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任饵溅,我火速辦了婚禮妨退,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜕企。我一直安慰自己咬荷,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布轻掩。 她就那樣靜靜地躺著幸乒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唇牧。 梳的紋絲不亂的頭發(fā)上罕扎,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音奋构,去河邊找鬼壳影。 笑死,一個胖子當(dāng)著我的面吹牛弥臼,可吹牛的內(nèi)容都是我干的宴咧。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼径缅,長吁一口氣:“原來是場噩夢啊……” “哼掺栅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纳猪,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤氧卧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后氏堤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沙绝,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年鼠锈,在試婚紗的時候發(fā)現(xiàn)自己被綠了闪檬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡购笆,死狀恐怖粗悯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情同欠,我是刑警寧澤样傍,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布横缔,位于F島的核電站,受9級特大地震影響衫哥,放射性物質(zhì)發(fā)生泄漏茎刚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一撤逢、第九天 我趴在偏房一處隱蔽的房頂上張望斗蒋。 院中可真熱鬧,春花似錦笛质、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姓迅,卻和暖如春敲霍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丁存。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工肩杈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人解寝。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓扩然,卻偏偏與公主長得像,于是被迫代替她去往敵國和親聋伦。 傳聞我的和親對象是個殘疾皇子夫偶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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