面試--js實現繼承的幾種方式

基於原型的繼承

function father() {
        this.faName = 'father';
        this.names=['11','22']
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function child() {
        this.chName = 'child';
    }
    child.prototype = new father();
    child.prototype.constructor = child;
    child.prototype.getchName = function() {
        console.log(this.chName);
    };
    var c1=new child();
    c1.names.push("sasa");
    var c2=new child();
    console.log(c2.names)   //原型上的names屬性被共享了 不是咱們所須要的

這種繼承會有以下的缺點:
一、若是父類包含有引用類型的屬性 全部的子類就會共享這個屬性。
二、在建立子類的實例時 不能向父類的構造函數傳遞參數es6

組合式繼承

原型繼承+構造函數的繼承app

function father(name) {
        this.faName = 'father';
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function child(args) {
        this.chName = 'child';
        father.apply(this,[]); //第二次調用父類構造函數
    }
    child.prototype = new father(); //第一次調用父類構造函數
    child.prototype.constructor = child;
    child.prototype.getchName = function() {
        console.log(this.chName);
    };

子類繼承父類的屬性,一組在子類實例上,一組在子類原型上(在子類原型上建立沒必要要的多餘的屬性)函數

寄生組合實現繼承

function father(name) {
        this.faName = 'father';
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function object(o) {    //建立一個原型爲o的新對象
        function F() {};
        F.prototype = o;
        return new F();
    }
    /**
     * 通用方法實現子類繼承父類
     * @param  {function} child  子類構造函數
     * @param  {function} father 被繼承的父類構造函數
     */
    function inheritPrototype(child, father) {
        var prototype = object(father.prototype); //建立一個指定原型的對象
        prototype.constructor = child; //加強對象
        child.prototype = prototype; //子類的原型等於該對象
    }
    function child(args) {
        this.chName = 'child';
        father.apply(this,[]);   //調用父類的構造函數能夠經過args傳遞參數
    }
    inheritPrototype(child, father); //子類的原型等於new 空函數(), 而new 空函數()出來的對象的原型等於父類的原型
    child.prototype.getchName = function() {
        console.log(this.chName);
    };
    console.log( child.prototype.isPrototypeOf(new child()) ); //true
    console.log(new child() instanceof child); //true

優勢:1.只調用一次父類的構造函數,避免了在子類原型上建立沒必要要的,多餘的屬性this

2.原型鏈保持不變

es6實現的繼承

class father{
        constructor(name){
            this.name=name
            this.names=[1,2,3]
        }
        getname(){
            console.log(this.name);
        }
    }
    class child extends father{
        constructor(name){
            super(name);
        }
        sayHello(){
            console.log("sayHello");
        }
        static hh(){
            console.log("hh")
        }
    }
    var cc=new child("juanjuan");
    cc.sayHello();
    cc.getname();  //juanjuan
    child.hh();  //hh
    cc.names.push("wqwq");
    var c1=new child("sasasa");
    console.log(c1.names)  //[1,2,3]
相關文章
相關標籤/搜索