1. 程式人生 > 其它 >ES5繼承_ 原型鏈繼承

ES5繼承_ 原型鏈繼承


ES5實現繼承的方法有6種,有5種都是有缺點的,我們直接說無缺點的最後一種,前面5種有的沒有達到下面說的實現準確繼承所需實現的部分,可自行百度

實現準確的繼承需要做好以下幾部分:

一、 屬性必須定義為例項屬性,即在this上定義屬性,這樣保證了屬性有引用值的時候,不會在多個例項之間共享

二、方法必須定義為原型屬性,即定義在建構函式的 protoType 上, 這樣保證了方法可以在多個例項之間共享,避免了在每個例項上都建立一遍方法

三、子類建構函式在例項化的時候必須要能夠給父類建構函式傳遞引數,這樣才能夠使子類例項擁有父類的屬性

四、必須避免冗餘現象,即無需在例項和原型上重複定義的屬性或方法

要達到以上幾方面,只有寄生式組合繼承

能夠完全做到,附程式碼:

// 父類建構函式
    function SuperType(name){
        // 滿足第一條,屬性必須為例項屬性,即定義在this上
        this.name=name;
        this.colors=['red','blue','green'];
    }
        // 滿足第二條,方法必須定位在原型上
    SuperType.protoType.sayName=function(){
        console.log(this.name);
    }

    // 子類建構函式
    function SubType(name,age){
        
// 滿足第三條,子類的建構函式在例項化的時候能夠給父類建構函式傳遞引數 SuperType.call(name); /* 注意這裡的 SuperType.call 必須放在定義例項屬性之前,確保了 SuperType 建構函式不會覆蓋 SubType 定義的屬性 */ this.age=age; } function inheritPrototype(subType,superType){ // 返回的protoType是空建構函式的例項,該例項的原型就是父類的原型 let protoType = object(superType.protoType); protoType.constructor
= subType; // 子類建構函式的原型指向了空建構函式返回的例項 subType.protoType = protoType; } /* 該函式做了3件事: 1 建立一個空的建構函式 2 將該函式的原型指向了傳進來的物件 3 返回建構函式的例項 */ function object(o){ function F(){}; F.protoType = o; return new F(); }

第四條是通過寄生式組合繼承解決了組合繼承重複在例項和原型上定義屬性。組合繼承程式碼:

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(name);
        this.age=age;
    }

    // 第二次呼叫父類建構函式,會在子類原型上定義屬性,造成冗餘現象
    SubType.protoType = new SuperType();