javascript的6中繼承方式

一.原型鏈繼承

首先,原型鏈?zhǔn)鞘裁??每一個構(gòu)造函數(shù)都有一個原型對象,原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個指向原型對象的內(nèi)部指針。讓原型對象等于另一個類型的實(shí)例,此時的原型對象將包含一個指向另一個原型對象的指針,而另一個原型對象中也包含一個指向;另一個構(gòu)造函數(shù)的指針。如此層層遞進(jìn),就構(gòu)成了實(shí)例與原型的鏈條。

        function SuperType(){
            this.name = '超類型';
            this.colors = ['red','blue','green'];
        }
        SuperType.prototype.age = 10; //給SuperType添加原型屬性
        function SubType(){

        }
        SubType.prototype = new SuperType();
        var instance1 = new SubType();
        console.log(instance1.age); // 10

SubType繼承了SupType,而繼承是通過創(chuàng)建SupType的實(shí)例,并將該實(shí)例賦值給SubType.prototype.

        function SuperType(){
            this.name = '超類型';
            this.colors = ['red','blue','green'];
        }
        SuperType.prototype.age = 10; //給SuperType添加原型屬性
        function SubType(){
        }
        SubType.prototype = new SuperType();
        var instance1 = new SubType();
        instance1.colors.push('black')
        var instance2 = new SubType();
        console.log(instance2.colors); // ["red", "blue", "green", "black"]

缺點(diǎn):
1.新實(shí)例無法向父類構(gòu)造函數(shù)傳參
2.SuperType的colors屬性包含一個數(shù)組(引用類型值),SubType.prototype繼承SuperType實(shí)例后;SubType的所有實(shí)例都會共享colors屬性。(包含引用類型值的屬性始終都會共享相應(yīng)的值)

二.借用構(gòu)造函數(shù)繼承

        function SuperType(name){
            this.name = name;
            this.colors = ['red','blue','green'];
        }
        SuperType.prototype.age = 10; //給SuperType添加原型屬性
        function SuperType1(sex){
            this.sex = sex;
        }
        function SubType(){
            SuperType.call(this, 'SubType');
        }
        var instance1 = new SubType();
        instance1.colors.push('black')
        var instance2 = new SubType();
        console.log(instance1.name) //SubType
        console.log(instance2.colors); // ["red", "blue", "green"]
        console.log(instance1.sex) //男
        console.log(instance2 instanceof SuperType);// false

特點(diǎn):
1.通過使用apply()和call()方法在新創(chuàng)建額對象上執(zhí)行構(gòu)造函數(shù)
2.在子實(shí)例中可向父實(shí)例傳參
3.解決了原型鏈繼承的問題
4.可以繼承多個構(gòu)造函數(shù)屬性(call多個)
缺點(diǎn):
1.果僅僅是借用構(gòu)造函數(shù),那么也將無法避免構(gòu)造函數(shù)模式存在的問題——方法都在構(gòu)造函數(shù)中定 義,因此函數(shù)復(fù)用就無從談起了
2.在父類型的原型中定義的方法,對子類型而言也是不可見的,結(jié)果所有類型只能使用構(gòu)造函數(shù)模式

三.組合繼承

組合繼承的思路是使用原型鏈繼承實(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(){
            console.log(this.name);
        }
        function SubType(name,age){
            SuperType.call(this,name);// 第二次調(diào)用SuperType();
            this.age = age;
        }
        SubType.prototype = new SuperType();// 第一次調(diào)用SuperType();
        SubType.prototype.constructor = SubType;
        SubType.prototype.sayAge = function(){
            console.log(this.age);
        }
        var instance1 = new SubType('instance1',10);
        instance1.colors.push('black');
        console.log(instance1.colors);// ["red", "blue", "green", "black"]
        instance1.sayName();//instance1
        instance1.sayAge();//10
        
        var instance2 = new SubType('instance2',11);
        console.log(instance2.colors);// ["red", "blue", "green"]
        instance2.sayName();//instance2
        instance2.sayAge();//11

特點(diǎn):結(jié)合了原型鏈繼承和借用構(gòu)造函數(shù)繼承的優(yōu)點(diǎn)
缺點(diǎn):
無論在什么情況下,都會調(diào)用兩次父類構(gòu)造函數(shù)

四.原型式繼承

原型式繼承繼承本質(zhì)是通過調(diào)用函數(shù),然后在函數(shù)內(nèi)部先創(chuàng)建一個臨時性的構(gòu)造函數(shù),然后將傳入的對象作為這個構(gòu)造函數(shù)的原型,最后返回這個臨時類型的一個新的構(gòu)造函數(shù)。函數(shù)對傳入其中的對象執(zhí)行了一次淺復(fù)制

        function object(o){ //Object.create()在傳入一個參數(shù)下,行為相同
            function F(){}; //先創(chuàng)建一個臨時性的構(gòu)造函數(shù)
            F.prototype = new o();//
            return new F();
        }
        var person ={
            name:'person',
            colors:['red','blue','green']
        }
        var anotherPerson = object(person);
        console.log(anotherPerson.name); // person

Object.create()接收兩個參數(shù),一個用作新對象原型的對向和一個為新對象定義額外屬性的對向。在傳入一個參數(shù)的情況下下,與object()的行為相同

        var newPerson = Object.create(person,{
            age:{
                value: 10
            }
        })
        console.log(newPerson.age); // 10

缺點(diǎn)和原型鏈繼承相似

五.寄生式繼承

    function object(o){ //Object.create()在傳入一個參數(shù)下,行為相同
            function F(){}; //先創(chuàng)建一個臨時性的構(gòu)造函數(shù)
            F.prototype = o;//
            return new F();
        }
    function createAnother(orgiginal){
        var clone = object(orgiginal);//通過調(diào)用函數(shù)創(chuàng)建一個新的對象
        clone.sayHi = function(){ //以某種方式來增強(qiáng)這個對象
            console.log(this.name);
        }
        return clone;//返回這個對象
    }
    var person = {
        name:'Nicholas',
        friends:['aa','bb','cc']
    }
    var anotherPerson = createAnother(person);
    anotherPerson.sayHi(); // Nicholas

在主要考慮對象而不是自定義類型和構(gòu)造函數(shù)的情況下,寄生式繼承也是一種有用的模式。示范使用的object()函數(shù)不是必須的;任何能夠返回新的對象的函數(shù)都適用于此模式
缺點(diǎn):函數(shù)不能復(fù)用

六.寄生組合式繼承

寄生組合式繼承,即通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法。其背后的基本思路是:不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),我們所需要的無非就是超類型原型的一個副本而已。本質(zhì)上,就是使用寄生式繼承來繼承超類型的原型,然后再將結(jié)果指定給子類型的原型。

    function inheritPrototype(subType, superType){
        var prototype = Object(superType.prototype); //創(chuàng)建對象
        prototype.constructor = subType;//增強(qiáng)對象
        subType.prototype = prototype; // 指定對象
    }
    function SuperType(name){
        trhis.name = name;
        this.colors = ['red','blue','green'];
    }
    SuperType.prototype.sayName=function(){
        console.log(this.name);
    }
    function SubType(name,age){
        SuperType.call(this,name);
        this.age = age;
    }
    inheritPrototype(SubType,SuperType);

inheritPrototype函數(shù)示例中,接收兩個參數(shù):子類型構(gòu)造函數(shù)和超類型構(gòu)造函數(shù)。在函數(shù)內(nèi)部,第一步是創(chuàng)建超類型原型的一個副本。第二步是為了創(chuàng)建的副本添加constructor屬性,從而彌補(bǔ)重新原型而失去默認(rèn)的constructor屬性。最后一步,將創(chuàng)建地 對象賦值給子類型的原型。
優(yōu)勢:解決了組合繼承兩次調(diào)用超類型構(gòu)造函數(shù)

Javascript主要通過原型鏈實(shí)現(xiàn)繼承。原型鏈的構(gòu)建是通過將一個類型的實(shí)例賦值給另一個構(gòu)造函數(shù)的原型實(shí)現(xiàn)的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容