[javascript高手之路]寄生組合式繼承的優勢

在之前javascript面向對象系列的文章裏面,我們已經探討了組合繼承和寄生繼承,回顧下組合繼承:

function Person( uName ){
            this.skills = [ 'php', 'javascript' ];
            this.userName = uName;
        }
        Person.prototype.showUserName = function(){
            return this.userName;
        }
        function Teacher ( uName ){
            Person.call( this, uName );
        }
        Teacher.prototype = new Person();
        var oT1 = new Teacher( 'ghostwu' );
        oT1.skills.push( 'linux' );
        var oT2 = new Teacher( 'ghostwu' );
        console.log( oT2.skills ); //php,javascript
        console.log( oT2.showUserName() ); //ghostwu

組合繼承有個缺點,父類的構造函數會被調用兩次.

第11行,設置子類原型對象(prototype),調用了第一次

第9行,實例化對象的時候,又調用一次

構造函數的目的是爲了複製屬性,第9行肯定是不能少的,第11行的目的是爲了獲取到父類原型對象(prototype)上的方法,基於這個目的,有沒有別的方法

可以做到 在不需要實例化父類構造函數的情況下,也能得到父類原型對象上的方法呢? 當然可以,我們可以採用寄生式繼承來得到父類原型對象上的方法

function Person( uName ){
            this.skills = [ 'php', 'javascript' ];
            this.userName = uName;
        }
        Person.prototype.showUserName = function(){
            return this.userName;
        }
        function Teacher ( uName ){
            Person.call( this, uName );
        }
        function object( o ){
            var G = function(){};
            G.prototype = o;
            return new G();
        }
        function inheritPrototype( subObj, superObj ){
            var proObj = object( superObj.prototype ); //複製父類superObj的原型對象
            proObj.constructor = subObj; //constructor指向子類構造函數
            subObj.prototype = proObj; //再把這個對象給子類的原型對象
        }
        inheritPrototype( Teacher, Person );
        var oT1 = new Teacher( 'ghostwu' );
        oT1.skills.push( 'linux' );
        var oT2 = new Teacher( 'ghostwu' );
        console.log( oT2.skills ); //php,javascript
        console.log( oT2.showUserName() ); //ghostwu

其實,說白了寄生組合式繼承就是一個借用構造函數 + 相當於淺拷貝父類的原型對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章