前端面試準備--6.面向?qū)ο?/h1>

面向?qū)ο?/strong>

1、類與實例

    1.1.類的聲明
    eg:
       1. function Animal(){
            this.name = "name";
        }
        
       2.ES6中類(class)的聲明
        class Animal2{
            constructor(){
                this.name = name;
            }
           
        }
    
    1.2.(如何通過類實例化生成對象)生成實例
    
    eg:
    //如果構(gòu)造函數(shù)后面沒有參數(shù)诊县,new后面這個()是可以不要的;
    1.console.log(new Animal(),new Animal2());

2媚污、類與繼承

    2.1.如何實現(xiàn)繼承富纸?
    2.2.繼承的幾種方式园担、各個形式都有什么優(yōu)點和缺點?
    
    繼承的本質(zhì)(原理)就是原型鏈缅糟。

1.借助構(gòu)造函數(shù)實現(xiàn)繼承

        (只實現(xiàn)了部分繼承挺智,如果父類的屬性都在構(gòu)造函數(shù)上,那沒有問題窗宦;
        如果父類的原型對象上還有方法赦颇,子類是拿不到這些方法的)
        
        function Parent1(){
            this.name = "parent1";
        }
        
        function Child(){
            //call和apply改變的是函數(shù)運行上下文,把父級(Parent1這個構(gòu)造函數(shù))在子函數(shù)里執(zhí)行的話赴涵,
            同時修改了父級構(gòu)造函數(shù)this的指向媒怯,從而導致了父類執(zhí)行的時候?qū)傩远紩煸贑hild類實例上去。
           
           //將父級的構(gòu)造函數(shù)的this指向一個子構(gòu)造函數(shù)的實例上去髓窜,父級構(gòu)造函數(shù)所有的屬性在子類中也有
            Parent1.call(this);
            this.type="child1";
        }
        
        console.log(new Child());
        
        缺點:Parent1原型鏈上的東西并沒有被Child所繼承扇苞;
        沒有繼承父類原型對象上的方法,導致的并沒有真正的實現(xiàn)繼承寄纵;
        function Parent1(){
            this.name ="Parent1";
        }
        
        Perent1.prototype.say=function(){};
        
        function Child1(){
            Parent1.call(this);
            this.type="child1";
        }
        
        console.log(new Child1(),new Child1().say());//say()不是一個function

2.借助原型鏈實現(xiàn)繼承(彌補構(gòu)造函數(shù)實現(xiàn)繼承不足)

        function Parent2(){
            this.name ="parent2";
        }
        
        function Child2(){
            this.type="child2";
        }
        
        //prototype作用為了讓這個構(gòu)造函數(shù)(Child2)的實例能訪問到原型對象上
        Child2.prototype = new Parent2();
        
        console.log(new Child2()); //Child2{type:"child2",__proto__:Parent2}
        console.log(new Child2().__proto__);//.__proto__===Child2.prototype
        new Child2.__proto__.name;--->"Parent2"
        
        缺點:
         function Parent2(){
            this.name ="parent2";
            this.play=[1,2,3];
        }
        
        function Child2(){
            this.type="child2";
        }
        
        Child2.prototype = new Parent2();
        console.log(new Child2());
        
        var s1= new Child2();
        var s2= new Child2();
        
        console.log(s1.play,s2.play);//[1,2,3];[1,2,3]
        
        s1.play.push(4);
        console.log(s1.play,s2.play);//[1,2,3,4];[1,2,3,4]
        
        在一個類上實例了兩個對象鳖敷,改第一個對象的屬性,第二個對象也跟著改變擂啥;
        引起這個問題的原因:原型鏈上的原型對象是共用的哄陶;
        s1.__proto__===s2.__proto__;//true

3.組合方式(實現(xiàn)繼承的通用方式)

        function Parent3(){
            this.name ="Parent3";
        }
        
        function Child3(){
            Parent3.call(this);//原型鏈上執(zhí)行了1次
            this.type="child3";
        }
        
        //父類的構(gòu)造函數(shù)執(zhí)行了2次
        Child3.prototype = new Parent3(); //new的時候執(zhí)行了一次
        
        var s3 = new Child3();
        var s4 = new Child3();
        s3.play.push(4);
        console.log(s3.play,s4.play);
        
        console.log(s3.constructor);//Parent3
         ----因為prototype直接拿的父類的實例,它沒有自己的constructor哺壶,它的constructor是從這個
         實例中繼承的屋吨,也就是原型鏈上一級拿過來的,它拿過來的肯定是Parent3的constructor山宾;
       
        缺點:父類的構(gòu)造函數(shù)執(zhí)行了2次

4.(組合繼承的優(yōu)化)

        //構(gòu)造函數(shù)體內(nèi)通過兩個構(gòu)造函數(shù)的組合能拿到所有構(gòu)造函數(shù)體內(nèi)的屬性和方法
        function Parent4(){
            this.name ="Parent4";
        }
        
        function Child4(){
            Parent4.call(this);//父類只執(zhí)行了一次
            this.type="child4";
        }
        
        //對象引用類型(優(yōu)點:原型對象是只是一個簡單的引用至扰,不會執(zhí)行父級的構(gòu)造函數(shù))
        Child4.prototype = Parent4.prototype;
        
        var s5 = new Child4();
        var s6 = new Child4();
        s5.play.push(4);
        
        console.log(s5.play,s6.play);
        
        
        //判斷這個對象是不是這個類的實例
        console.log(s5 instanceof Child4,s5 instanceof Parent4);//true,true
   
    問題:怎么區(qū)分一個對象是直接由它的子類實例化的,還是它的父類實例化的资锰?
    (怎么區(qū)分s5是是Child4的實例還是Parent4直接實例化的敢课?)
    
    
        //指向了父類Parent4{this.name="parent4";this.play=[1,2,3]}
        console.log(s5.constructor); 
        
        ---prototype里面有一個屬性constructor,而我們的子類原型對象和父類的原型對象是一個對象绷杜,這個對象的constructor
        就是父類里的constructor直秆,這個父類的constructor指的是Parent4自己;
      
       ----因為prototype直接拿的父類的實例,它沒有自己的constructor鞭盟,它的constructor是從這個
         實例中繼承的圾结,也就是原型鏈上一級拿過來的,它拿過來的肯定是Parent4的constructor齿诉;

5.組合繼承優(yōu)化2(完美版)

    function Parent5(){
        this.name ="name";
        this.play=[1,2,3];
    }
    
    function Child5(){
        Parent5.call(this);
        this.type="Child5";
    }
    
    
    //Object.create創(chuàng)建對象的原理:
    //--- Child4.prototype = Parent4.prototype;引用同一個對象筝野,說白是一個對象晌姚,缺點:它倆的構(gòu)造函數(shù)指向的是一個
    (constructor是一個)無法區(qū)分實例是由父類創(chuàng)建的還是子類創(chuàng)建的;
    
    //---Object.create(Parent5.prototype)歇竟;創(chuàng)建中間對象方法挥唠,就把兩個原型對象區(qū)分開,這個中間對象還具備一個特性就是它的原型
    對象是父類的原型對象焕议,這樣在原型鏈上又開始連起來了宝磨。
     --通過在給Child5原型對象上的constructor做修改,就能正常區(qū)分父類和子類的構(gòu)造函數(shù)了号坡。
   
    Child5.prototype = Object.create(Parent5.prototype);
    Child5.prototype.constructor = Child5;
    
    var s7 = new Child5();
    var s8 = new Child5();
    
    s6.play.push(4);
    
    console.log(s7 instanceof Child5,s7 instanceof Parent5);//true true
    consoel.log(s7.constructor); //Child5
    
    
***為什么通過Object.create方法創(chuàng)建的這個對象就能作為它倆之間的橋梁呢懊烤?
    Object.create創(chuàng)建的對象有什么特點?
    --Object.create它創(chuàng)建的這個對象宽堆,原型對象就是參數(shù)腌紧;
    
原理:Child5實例的原型對象等于Child5.prototype,Child5.prototype又等于Object.create方法創(chuàng)建的對象,這個中間對象原型對象又是
(prototype)父類的原型對象畜隶,所以一級的上一級的上一級壁肋,通過這樣找實現(xiàn)了繼承;而且還達到了父類和子類原型對象的隔離籽慢;
    
對象通過.__proto__ (這個屬性往上找它的原型對象的)一級一級往上找浸遗;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個濱河市箱亿,隨后出現(xiàn)的幾起案子跛锌,更是在濱河造成了極大的恐慌,老刑警劉巖届惋,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件髓帽,死亡現(xiàn)場離奇詭異,居然都是意外死亡脑豹,警方通過查閱死者的電腦和手機郑藏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瘩欺,“玉大人必盖,你說我怎么就攤上這事【愣觯” “怎么了歌粥?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拍埠。 經(jīng)常有香客問我阁吝,道長,這世上最難降的妖魔是什么械拍? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任突勇,我火速辦了婚禮,結(jié)果婚禮上坷虑,老公的妹妹穿的比我還像新娘甲馋。我一直安慰自己,他們只是感情好迄损,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布定躏。 她就那樣靜靜地躺著,像睡著了一般芹敌。 火紅的嫁衣襯著肌膚如雪痊远。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天氏捞,我揣著相機與錄音碧聪,去河邊找鬼。 笑死液茎,一個胖子當著我的面吹牛逞姿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捆等,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼滞造,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栋烤?” 一聲冷哼從身側(cè)響起谒养,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎明郭,沒想到半個月后买窟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡达址,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年蔑祟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沉唠。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡疆虚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出满葛,到底是詐尸還是另有隱情径簿,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布嘀韧,位于F島的核電站篇亭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锄贷。R本人自食惡果不足惜译蒂,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一曼月、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柔昼,春花似錦哑芹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乙嘀,卻和暖如春末购,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虎谢。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工盟榴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘉冒。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓曹货,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讳推。 傳聞我的和親對象是個殘疾皇子顶籽,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

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