原型繼承

一、原型判斷方法
*術(shù)語(yǔ)解釋:成員=屬性+方法
實(shí)例成員:實(shí)例屬性和實(shí)例方法
原型成員:原型對(duì)象屬性和原型對(duì)象方法
1箕戳、原型對(duì)象:每個(gè)構(gòu)造函數(shù)都有一個(gè)與之相關(guān)聯(lián)的對(duì)象,這個(gè)對(duì)象稱之為原型對(duì)象躏率。 (相關(guān)聯(lián)是指通過(guò)一個(gè)prototype屬性來(lái)連接這個(gè)對(duì)象衩侥,然后原型對(duì)象可以通過(guò) constructor回到構(gòu)造函數(shù))
2、特點(diǎn):構(gòu)造函數(shù)的原型對(duì)象上的所有屬性和方法會(huì)被構(gòu)造函數(shù)創(chuàng)建出來(lái)的所有對(duì)象共享刨晴。

3屉来、 訪問(wèn)原型對(duì)象:(1) prototype
(2)proto
(3)object.getPrototypeof()
4、設(shè)置原型對(duì)象:(1)動(dòng)態(tài)特性(利用prototype屬性直接添加狈癞,)
(2)使用字面量替換(1茄靠、在替換前創(chuàng)建出的對(duì)象和替換后創(chuàng)建出的對(duì)象,他們所指向的原型對(duì)象不是同一個(gè)原型對(duì)象蝶桶。2慨绳、修改constructor指向)
(3)系統(tǒng)的原型對(duì)象只可以添加屬性和方法,不能替換或刪除真竖。

5脐雪、(1)hasownproperty: 檢查對(duì)象中是否存在制定的屬性(不包含原型成員)。
作用:過(guò)濾處理恢共,過(guò)濾原型對(duì)象成員战秋。
(2) in 檢查對(duì)象中是否存在制定的屬性(包含原型成員)。
(3)isPrototypeof()檢查某個(gè)對(duì)象是否是指定對(duì)象的原型對(duì)象讨韭。(包含原型鏈)
(4)object.getpototypeof():獲取某個(gè)對(duì)象的原型對(duì)象脂信。
(5)instanceof :判斷某個(gè)構(gòu)造函數(shù)的原型對(duì)象是否在當(dāng)前的原型鏈上面。

6透硝、call方法和apply方法:借用其他對(duì)象的方法狰闪,并且綁定方法的內(nèi)部this。方法是在函數(shù)Fuction原型對(duì)象上的濒生。所有的函數(shù)對(duì)象都可以調(diào)用埋泵。

<script>
 var obj={
     name:'jane',
     show: function (a,b) {
         console.log(this.name + ":" + a + b);
     }
 };
var obj1={name:'jack '  };
      obj.show(1,2);
     obj.show.call(obj1,2,2); //方法在調(diào)用時(shí)會(huì)立刻執(zhí)行。后面的參數(shù)借用前者方法甜攀。
                                         //實(shí)參傳遞不是應(yīng)該寫(xiě)在調(diào)用函數(shù)的后面秋泄。
</script>
    call和 aplly區(qū)別:傳參方式不同琐馆,call可以接受多個(gè)參數(shù),但apply方法只接受連兩個(gè)參數(shù)恒序,后面的實(shí)參需要寫(xiě)入到一個(gè)字符串中瘦麸;
                                 形參的默認(rèn)長(zhǎng)度不一樣。(函數(shù)的length屬性歧胁,獲取的是函數(shù)形參的個(gè)數(shù))

7.this關(guān)鍵字:指向一個(gè)對(duì)象滋饲,具體到某一個(gè)由當(dāng)前上下文決定。在函數(shù)的內(nèi)部喊巍,和函數(shù)的調(diào)用方法有關(guān)屠缭。
7.1函數(shù)調(diào)用方式: A、直接調(diào)用(指向window)
function demo1(){ console.log(this); }
demo1();//
B崭参、對(duì)象的方法調(diào)用(指向調(diào)用該方法的object)
function demo1(){ console.log(this);}
var obj={}
obj.demo=demo1;
obj.demo();
C:構(gòu)造函數(shù)的方式調(diào)用(指向新創(chuàng)建的對(duì)象)
function demo1(){ console.log(this);}
var obj= new demo1();
console.log(obj);
D:函數(shù)上下文調(diào)用(傳遞的第一個(gè)參數(shù))
call和apply
7.2(重點(diǎn))this的對(duì)視問(wèn)題
var demo1={
name:'123',
show: function () {
console.log(this.name)}
};
var t=demo1.show;
t();
用函數(shù)t直接調(diào)用對(duì)象方法時(shí)呵曹,相當(dāng)于在賦值之后,已經(jīng)脫離了原對(duì)象何暮,此時(shí)t內(nèi)部的this變量已經(jīng)獨(dú)立出來(lái)奄喂,和源對(duì)象沒(méi)有了關(guān)系,此時(shí)的this已經(jīng)指向了Window海洼,運(yùn)行后跨新,在window中查詢自定義的方法,未查詢到的情況下輸出空字符坏逢。

8.tostring方法:轉(zhuǎn)換為字符串域帐,以字符串的方式來(lái)描述對(duì)象。 返回值是一個(gè)數(shù)組是整,有兩個(gè)參數(shù)肖揣,他們分別表示 [對(duì)象類型,構(gòu)造函數(shù)類型]
但數(shù)組類型的返回值是數(shù)組中的值浮入,原因在于數(shù)組的tostring方法在數(shù)組的原型對(duì)象中單獨(dú)存在许饿,所以需要借用對(duì)象類型原型的方法來(lái)做為判斷,
Object.prototype.toString.call()

  1. Array.isAarray判斷某個(gè)對(duì)象是否是數(shù)組類型舵盈。
    注意點(diǎn):這個(gè)方法是ES5的,存在兼容性問(wèn)題球化。需要自定義一個(gè)函數(shù)來(lái)解決此問(wèn)題秽晚。

二、繼承
1筒愚、繼承分類:(1)赴蝇、基于接口的繼承(2)基于實(shí)現(xiàn)的繼承
2、javascript使用了一種獨(dú)特繼承機(jī)制——原型繼承(不包含原型成員 )巢掺。prototype屬性句伶,是建立這種機(jī)制的關(guān)鍵劲蜻,這個(gè)屬性存在于每一個(gè)構(gòu)造函數(shù)中。
3考余、實(shí)現(xiàn)方式:
(1)屬性拷貝
1.1 屬性拷貝分為:淺拷貝和深拷貝
存在問(wèn)題:A、如果要拷貝多個(gè)對(duì)象需要多次for……in循環(huán)。B焕蹄、如果屬性是引用類型塔粒,存在共享問(wèn)題;
解決問(wèn)題A:使用object.assign來(lái)解決多次拷貝問(wèn)題身冬。
作用:拷貝對(duì)個(gè)對(duì)象的屬性衅胀。
語(yǔ)法:object.assign(目標(biāo)對(duì)象,源對(duì)象1酥筝,源對(duì)象2 …………)
注意點(diǎn):---ES6退出的新方法滚躯,使用需要注意兼容性。
---存在同名屬性會(huì)被按照參數(shù)順序覆蓋嘿歌。
---有返回值掸掏,為目標(biāo)對(duì)象。
---如果只傳遞一個(gè)參數(shù)搅幅,直接返回當(dāng)前對(duì)象阅束。如果不是對(duì)象,會(huì)轉(zhuǎn)
換為對(duì)應(yīng)的包裝對(duì)象茄唐。
---如果是null或者undefined息裸,會(huì)報(bào)錯(cuò)。
---目標(biāo)對(duì)象正常沪编,其他值會(huì)忽略處理其他值呼盆。字符串會(huì)特殊處理為
數(shù)組對(duì)象來(lái)處理,
---同樣存在共享問(wèn)題蚁廓。
1.2 用深拷貝解決共享問(wèn)題:
淺拷貝在對(duì)對(duì)象進(jìn)行拷貝時(shí)访圃,傳遞的是地址,所以存在數(shù)據(jù)共享的問(wèn)題相嵌。
方案:遍歷對(duì)象的過(guò)程中腿时,值類型直接賦值,屬性為引用類型饭宾,添加一個(gè)引用類型的屬性批糟,添加的時(shí)被添加的對(duì)象中并不存在一個(gè)引用類型的值,所以需要在內(nèi)部初始化一個(gè)引用類型看铆。屬性的值為一個(gè)引用類型徽鼎,然后遍歷,再賦值。
具體代碼實(shí)現(xiàn):

function deepcopy(obj,obj1){
    obj=obj||{};
    for(var key  in obj1){
        if(typeof obj1[key]=='object'){
                        obj[key]={};
                 deepcopy(obj[key],obj1[key])
        }else{
                 obj[key]=obj1[key]
        }
    }
}

存在缺點(diǎn):在循環(huán)遍歷初始化中否淤,無(wú)法對(duì)數(shù)組類型做出正確的判斷悄但,被解析成了object類型屬性,所以需要進(jìn)行改進(jìn)石抡。
在添加對(duì)象初始化中:用Array.isArray判斷:
obj[key]=Array.isArray(obj1[key])?[]:{};

                    (2)原型式繼承
                            第一種實(shí)現(xiàn)方式:
                               1.1 ---提供構(gòu)造函數(shù)
                               1.2---設(shè)置構(gòu)造函數(shù)原型的成員
                               1.3---直接在原型對(duì)象寫(xiě)入方法的缺點(diǎn):
                            (a) 團(tuán)隊(duì)開(kāi)發(fā)會(huì)出現(xiàn)相同屬性名覆蓋的問(wèn)題檐嚣,造成混亂,
                            (b)性能不好汁雷,和屬性的訪問(wèn)方式相關(guān)净嘀,原型對(duì)象的屬性增
                                    多,遍歷的復(fù)雜度會(huì)上升侠讯。
                            1.4--- 如何克服缺點(diǎn):安全擴(kuò)展原型對(duì)象 
                                  提供自己的構(gòu)造函數(shù)挖藏;設(shè)置構(gòu)造函數(shù)的原型對(duì)象;在自己提
                            供的構(gòu)造函數(shù)原型對(duì)象上添加成員厢漩;然后用自己的構(gòu)造函數(shù)創(chuàng)建
                           對(duì)象膜眠。引出了第二種實(shí)現(xiàn)方式。

                           第二種實(shí)現(xiàn)方式:
                                1.1 ---提供構(gòu)造函數(shù)
                                1.2---設(shè)置構(gòu)造函數(shù)原型對(duì)象溜嗜,然后替換掉構(gòu)造函數(shù)原來(lái)的原
                             型宵膨。
                            對(duì)象,并且同時(shí)需要修正構(gòu)造器的constructior屬性炸宵,使它指向原
                            實(shí)例對(duì)象的構(gòu)造函數(shù)辟躏。
                            
                         第三種實(shí)現(xiàn)方法:
                           1.1---提供父構(gòu)造函數(shù)
                           1.2---設(shè)置父構(gòu)造函數(shù)的原型對(duì)象
                           1.3---提供子構(gòu)造函數(shù)
                           1.4---設(shè)置子構(gòu)造函數(shù)的原型對(duì)象
                           1.5---創(chuàng)建對(duì)象(子函數(shù)原型對(duì)象替換為父函數(shù)原型對(duì)象)
                   缺點(diǎn):a:無(wú)法獲取父構(gòu)造函數(shù)的實(shí)例成員;b:存在共享問(wèn)題土全。
                            無(wú)法共享的可以通過(guò)原型鏈來(lái)解決(原型鏈繼承)捎琐,但依然存在
                  共享問(wèn)題。

                    (3)原型鏈繼承
                         ** 原型鏈結(jié)構(gòu):
                         1.1 所有的對(duì)象都是由構(gòu)造函數(shù)創(chuàng)建出來(lái)裹匙,每個(gè)對(duì)象都有相對(duì)應(yīng)的
                  構(gòu)造函數(shù)瑞凑,
                         1.2每個(gè)構(gòu)造函數(shù)都有一個(gè)與之相關(guān)聯(lián)的原型對(duì)象。 
                         1.3構(gòu)造函數(shù)原型對(duì)象本身也是對(duì)象概页,因此籽御,構(gòu)造函數(shù)原型對(duì)象也
                   有自己的構(gòu)造函數(shù)。 
                         1.4構(gòu)造函數(shù)原型對(duì)象的構(gòu)造函數(shù)也有相關(guān)聯(lián)的原型對(duì)象惰匙。而這個(gè)
                  原型對(duì)象也是對(duì)象技掏。
                     以上是一種鏈?zhǔn)降脑L問(wèn)結(jié)構(gòu),JS對(duì)原型鏈的終點(diǎn)進(jìn)行了特殊處理项鬼,
                object.prototype._prto_=null零截。
                          ** 原型鏈搜索規(guī)則:對(duì)象在訪問(wèn)屬性時(shí),首先在自身查找秃臣,然后
                 去自己的原型對(duì)象,然后去原型對(duì)象的原型對(duì)象。一直重復(fù)到找到奥此。
                 屬性和方法在位沒(méi)有找到的情況下弧哎,會(huì)出現(xiàn)屬性未定義,方法報(bào)錯(cuò)的情
                 況稚虎。
                     1.5 注意點(diǎn):a:代碼的書(shū)寫(xiě)順序撤嫩,完成原型鏈繼承之后,再修改
               constructor屬性指向構(gòu)造函數(shù)蠢终,然后添加原型成員序攘;b:無(wú)法向父函數(shù)傳遞
               參數(shù)。父構(gòu)造函數(shù)的實(shí)例對(duì)象的實(shí)例成員會(huì)自動(dòng)成為子構(gòu)造函數(shù)的實(shí)例
               成員的原型成員寻拂。
                    1.6 object.create()該方法用來(lái)創(chuàng)建一個(gè)對(duì)象程奠,并且設(shè)置創(chuàng)建的對(duì)象的
             原型對(duì)象為他括號(hào)內(nèi)參數(shù)指定的某一對(duì)象。
                            注意點(diǎn):ES5推出的祭钉,有兼容性問(wèn)題瞄沙,(自定義一個(gè)新方法)
           實(shí)現(xiàn)步驟為:先自定義一個(gè)空函數(shù)后,并設(shè)置其原型對(duì)象慌核,然后返回距境。
<script>
   function Animal(){
    this.color='紅色的老王';
   };
Animal.eat= function () {
    console.log('eat');
}
   function Person(){
       this.name='人中老王';
   }
   Person.prototype= new Animal();
   Person.prototype.constructor=Person;
   Person.prototype.say= function () {
       console.log('hello');
   }
   function Student(){
  this.number='123456789'
   }
   Student.prototype=new Person();
   Student.prototype.constructor=Student;
   Student.prototype.study= function () {
       console.log('study');
   }
    function  Boy(){
        this.GF='鳳姐';
    }
   Boy.prototype=new Student();
   Boy.prototype.constructor=Boy;
   Boy.prototype.play= function () {
       console.log('王者榮耀');
   }
var b=new Boy()
   console.log(b);
</script>

      存在問(wèn)題:無(wú)法向父構(gòu)造函數(shù)傳遞參數(shù)。
                        共享問(wèn)題垮卓。
                 

                   (4)借用構(gòu)造函數(shù)(經(jīng)典繼承)

函數(shù)的創(chuàng)建:a.直接聲明垫桂,
b.函數(shù)表達(dá)式(匿名式,命名式【使用命名式創(chuàng)建函數(shù)后粟按,關(guān)鍵字后function后的名稱只提供給內(nèi)部調(diào)用】)
c.使用構(gòu)造函數(shù)創(chuàng)建 var fuc = new function(形參1诬滩,形參2,函數(shù)體)

<script>
 function Person(name,age){
        //this值得是Person的實(shí)例對(duì)象
        this.name = name;
        this.age = age;
    }
    new Person();
    Person.prototype.showName = function(){
        console.log(this.name);
    }
    function Man(GF,name,age)
    {
        this.GF = GF;
        //調(diào)用Person函數(shù),并且綁定Person函數(shù)內(nèi)部的this為第一個(gè)參數(shù),也就是Man的實(shí)例對(duì)象,也就是this
        //獲得父構(gòu)造函數(shù)中的實(shí)例對(duì)象的實(shí)例成員并且傳遞參數(shù)
        Person.call(this,name,age);
    }
    Man.prototype = new Person();
    var m1 = new Man("范冰冰","小米",12);
    var m2 = new Man("李冰冰","小麥",21);
    //要求:m1要能夠擁有父構(gòu)造函數(shù)(Person)的實(shí)例對(duì)象上面的實(shí)例成員 和原型成員
    console.log(m1);
    console.log(m2);
<script>
                   (5)組合繼承1(原型式+借用構(gòu)造函數(shù))
<script>
    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype.showName = function(){
        console.log(this.name);
    }

    function Man(GF,name,age)
    {
        this.GF = GF;
        Person.call(this,name,age);
    }
    Man.prototype = Person.prototype;
    var m1 = new Man("范冰冰","小米",12);
    console.log(m1);
    m1.showName();
</script>

依然會(huì)存在共享的問(wèn)題钾怔,需要使用深拷貝解決碱呼。
(6)組合繼承2(深拷貝+借用構(gòu)造函數(shù))

    function deepcopy(obj,obj1){
        obj=obj||{};
        for(var key  in obj1){
            if(typeof obj1[key]=='object'){
                obj[key]={};
                deepcopy(obj[key],obj1[key])
            }else{
                obj[key]=obj1[key]
            }
        }
    }
    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype.eat = function(){
        console.log(this.name);
    }

    function Man(GF,name,age)
    {
        this.GF = GF;
        Person.call(this,name,age);
    }
    deepcopy(Person.prototype,Man.prototype);
    var m1 = new Man("范冰冰","小米",12);
    console.log(m1);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宗侦,隨后出現(xiàn)的幾起案子愚臀,更是在濱河造成了極大的恐慌,老刑警劉巖矾利,帶你破解...
    沈念sama閱讀 210,835評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姑裂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡男旗,警方通過(guò)查閱死者的電腦和手機(jī)舶斧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)察皇,“玉大人茴厉,你說(shuō)我怎么就攤上這事泽台。” “怎么了矾缓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,481評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵怀酷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我嗜闻,道長(zhǎng)蜕依,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,303評(píng)論 1 282
  • 正文 為了忘掉前任琉雳,我火速辦了婚禮样眠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翠肘。我一直安慰自己檐束,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,375評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布锯茄。 她就那樣靜靜地躺著厢塘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肌幽。 梳的紋絲不亂的頭發(fā)上晚碾,一...
    開(kāi)封第一講書(shū)人閱讀 49,729評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音喂急,去河邊找鬼格嘁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛廊移,可吹牛的內(nèi)容都是我干的糕簿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,877評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼狡孔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼懂诗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起苗膝,我...
    開(kāi)封第一講書(shū)人閱讀 37,633評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤殃恒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后辱揭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體离唐,經(jīng)...
    沈念sama閱讀 44,088評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,443評(píng)論 2 326
  • 正文 我和宋清朗相戀三年问窃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亥鬓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,563評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡域庇,死狀恐怖嵌戈,靈堂內(nèi)的尸體忽然破棺而出覆积,到底是詐尸還是另有隱情,我是刑警寧澤咕别,帶...
    沈念sama閱讀 34,251評(píng)論 4 328
  • 正文 年R本政府宣布技健,位于F島的核電站,受9級(jí)特大地震影響惰拱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啊送,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,827評(píng)論 3 312
  • 文/蒙蒙 一偿短、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馋没,春花似錦昔逗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,712評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至声旺,卻和暖如春笔链,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腮猖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,943評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工鉴扫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人澈缺。 一個(gè)月前我還...
    沈念sama閱讀 46,240評(píng)論 2 360
  • 正文 我出身青樓坪创,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親姐赡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莱预,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,435評(píng)論 2 348

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