原型、原型鏈胞此、繼承(構(gòu)造函數(shù)繼承恶迈,非構(gòu)造函數(shù)繼承)

一涩金、原型

在JS設(shè)計出來的時候,只是為了實現(xiàn)一樣網(wǎng)頁的簡單交互暇仲,并沒有想過把JS設(shè)計成為一門面向?qū)ο蟮恼Z言步做。后來的發(fā)展,JAVA和C++等語言都有了自己的Class用于繼承奈附,所以JS也想要實現(xiàn)繼承全度,所以就出現(xiàn)了原型prototype

二、原形鏈

function Person(){
}
 var p = new Person()

對應的原型鏈結(jié)構(gòu)為


每個構(gòu)造函數(shù)都有一個原型屬性prototype
每個對象都有 __proto__ 屬性斥滤,指向了創(chuàng)建該對象的構(gòu)造函數(shù)的原型将鸵。其實這個屬性指向了 [[prototype]]勉盅,但是 [[prototype]] 是內(nèi)部屬性,我們并不能訪問到咨堤,所以使用 _proto_來訪問菇篡。

對象可以通過 __proto__來尋找不屬于該對象的屬性漩符,__proto__ 將對象連接起來組成了原型鏈

默認的原型鏈就是:
當前對象-->構(gòu)造函數(shù).prototype-->Object.prototype-->null

注意: 原型和實例上都有一個constructor構(gòu)造器指向構(gòu)造函數(shù)
Function.prototype.constructor === new Function().constructor

三.構(gòu)造函數(shù)繼承

構(gòu)造繼承
原型繼承
實例繼承(閉包繼承)
拷貝繼承
組合繼承
寄生組合繼承

優(yōu)缺點考慮方向: 實例化的次數(shù)一喘,是否父類子類實例,是否可以復用

1.構(gòu)造繼承

使用父類的構(gòu)造函數(shù)來增強子類實例嗜暴,等于賦值父類的實例屬性給子類

    function Animal(){
        this.species  = "動物";
    }
    function Cat(name){
        Animal.call(this)
        Animal.apply(this)
        //相當于 Animal()
        //this.species = '動物' this指向Cat內(nèi)部
        console.log(this)//Cat
        this.name = name;
    }

    var cat = new Cat("大毛")

缺點:
1.實例并不是父類的實例凸克,只是子類的實例
2.只能繼承父類的實例屬性和方法,不能繼承原型屬性和方法

2.原型繼承

使用構(gòu)造函數(shù)的prototype指向父對象的一個實例,需要注意把子構(gòu)造函數(shù)的constructor構(gòu)造器重新指向自己闷沥,因為使用prototype指向了父構(gòu)造函數(shù)的prototype,會出現(xiàn)原型鏈紊亂

    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;
   var cat1 = new Cat("大毛","黃色");
   alert(cat1.species); // 動物

原型繼承升級版

 function Animal(){ }
 Animal.prototype.species = "動物";

   Cat.prototype = Animal.prototype;
   Cat.prototype.constructor = Cat;
   var cat1 = new Cat("大毛");
   alert(cat1.species); // 動物

缺點:
1.無法實現(xiàn)多繼承
2.創(chuàng)建子類實例時萎战,無法想父類構(gòu)造函數(shù)傳參

3.實例繼承

為父類實例添加新特性,作為子類實例返回

function Cat(name){
  var instance = new Animal();
  instance.name = name || '';
  return instance;
}
var cat1 = new Cat('大毛')

缺點
1.實例是父類的實例舆逃,不是子類的實例
2.不支持多繼承

4.拷貝繼承

把父對象的所有屬性和方法蚂维,拷貝進子對象

  function Animal(){}
 Animal.prototype.species = "動物";

 function Cat(name){
     this.name = name;
  }
  function extend(Child, Parent) { 
     var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
      c[i] = p[i];
      }
  }

extebd(Cat, Animal)
var cat1 = new Cat('大毛')
alert(cat1.species)

缺點:
1.效率低,內(nèi)存占用高(因為需要拷貝父類的屬性)
2.無法拷貝對象和數(shù)組

5.組合繼承
通過調(diào)用父類構(gòu)造路狮,繼承父類的屬性并保留可以傳參虫啥,然后通過將父類實例作為子類原型,實現(xiàn)函數(shù)復用

function Animal(){ this.species = '動物'}
function Cat(name){
   Animal.apply(this)
  this.name = name
}
Cat.prototype = new Animal()
Cat.prototype.constructor = Cat
var cat1 = new Cat('大毛')

優(yōu)點:
1.可以繼承實例屬性和方法也可以繼承原型方法
2.即是子類的實例奄妨,也是父類的實例
3.可傳參
4.函數(shù)可復用
缺點: 調(diào)用了兩次父類構(gòu)造函數(shù)涂籽,生成了兩份實例

寄生組合繼承
通過計生方式,去掉父類的實例屬性砸抛,這樣评雌,在調(diào)用兩次父類的構(gòu)造函數(shù)的時候,就不會初始化兩次實例

function Cat(name){
  Animal.call(this)
  this.name = name 
}
(function(){
  //創(chuàng)建一個沒有實例方法的類
  var Supe = function(){}
  Super.prototype = Animal.prototype
  //將實例作為子類的原形
  Cat.prototype = new Super()
  Cat.prototype.constructor = Cat
}())

var cat = new Cat('大毛')

優(yōu)點
1.比起組合繼承直焙,減少了一次實例化父類景东,節(jié)省內(nèi)存

四、非構(gòu)造函數(shù)的繼承

object()繼承
淺拷貝
深拷貝

1.objecc()繼承
實現(xiàn)object()函數(shù)奔誓,把子對象的prototype屬性耐薯,指向父對象,使得父子對象連在一起

function object(o){
  function F(){}
  F.prototype = o
  return new F()
}
var guangzhou = object(Chinese)

2.淺拷貝
把父對象的屬性丝里,全部拷貝給子對象曲初,也能實現(xiàn)繼承

function copy(p){
  var c = {}
  for(var i in p){//[]則遍歷牽引值 {}則遍歷屬性名
    c[i] = p[i]  
  }
  return c
}

3.深拷貝
深拷貝,能夠?qū)崿F(xiàn)真正意義上的數(shù)組和對象的拷貝杯聚,只需要遞歸地調(diào)用淺拷貝

function deepCopy(p,c){
  var c = c || {}
  for(var i in p){
    if(typeof i === 'object'){ //typeof arr && typeof object => object
    var c[i] = (p[i].constructor === Array) ? []: {}
    deepCopy(p[i], c[i])   
    }else{
      c[i] = p[i]
    }
  }
return c
}

JS繼承的實現(xiàn)方式
深度解析原型中的各個難點

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末臼婆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幌绍,更是在濱河造成了極大的恐慌颁褂,老刑警劉巖故响,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颁独,居然都是意外死亡彩届,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門誓酒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來樟蠕,“玉大人,你說我怎么就攤上這事靠柑≌纾” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵歼冰,是天一觀的道長靡狞。 經(jīng)常有香客問我,道長隔嫡,這世上最難降的妖魔是什么甸怕? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮腮恩,結(jié)果婚禮上梢杭,老公的妹妹穿的比我還像新娘。我一直安慰自己庆揪,他們只是感情好式曲,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缸榛,像睡著了一般吝羞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上内颗,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天钧排,我揣著相機與錄音,去河邊找鬼均澳。 笑死恨溜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的找前。 我是一名探鬼主播糟袁,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼躺盛!你這毒婦竟也來了项戴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤槽惫,失蹤者是張志新(化名)和其女友劉穎周叮,沒想到半個月后辩撑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡仿耽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年合冀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片项贺。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡君躺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敬扛,到底是詐尸還是另有隱情晰洒,我是刑警寧澤朝抖,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布啥箭,位于F島的核電站,受9級特大地震影響治宣,放射性物質(zhì)發(fā)生泄漏急侥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一侮邀、第九天 我趴在偏房一處隱蔽的房頂上張望坏怪。 院中可真熱鬧,春花似錦绊茧、人聲如沸铝宵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹏秋。三九已至,卻和暖如春亡笑,著一層夾襖步出監(jiān)牢的瞬間侣夷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工仑乌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留百拓,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓晰甚,卻偏偏與公主長得像衙传,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子厕九,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

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