js繼承的幾種方式


最近在面試的時候,遇到過兩次問繼承實現的幾種方式,這里能我給大家列舉了以下的這幾種,給大家參考參考

方式一:借助構造函數實現繼承

這里使用的原理就是在Child里面,把Parent的this指向改為是Child的this指向,從而實現繼承

function Parent(name){
    this.name=name;
    }
    Parent.prototype.saiHi=function(){
        console.log("hello")
    }
    function Child(name,age,gender){
        Parent.call(this,name)
        this.age=age;
        this.gender=gender;
    }
    let child=new Child("王磊",20,"男")
    console.log(child.name);// 王磊
    child.sayHi(); // Uncaught TypeError:child.sayHi is not a function

缺點:只能解決屬性的繼承,使用屬性的值不重復,但是父級類別的方法不能繼承

方式二:借助原型鏈實現繼承

第二種方式就是把Child的原型改為是Parent的實例,從而實現繼承

     function Parent(name,gender){
            this.name=name;
            this.gender=gender;
            this.list=[1,2,3]
        }
        Parent.prototype.eat=function(){
            console.log("晚餐時間到")
        }
        function Child(age){
            this.age=age;
        }
        Child.prototype=new Parent("李白","男");
        var child=new Child(20);
        var child2=new Child(30);
        child.eat();
        console.log(child.list,child2.list);// [1,2,3] [1,2,3]
        child.list.push(4)
        console.log(child.list);// [1,2,3,4]        
        console.log(child2.list);// [1,2,3,4]

缺點:因為Child的原型對象都是New Parent,所以實例化出來的對象的屬性都是一樣的,而且Parent上面的引用類型只要有一個實例對象修改了,其他也會跟着修改.因為他們原型對象都是共用的

方式三:組合型

方式三的話是結合了方式一和方式二來實現繼承

function Person(school){
            this.school=school;
        }
        Person.prototype.skill=function(){
            console.log("學習");
        }
        function Student(school,name,age,gender){
            Parent.call(this,school);
            this.name=name;
            this.age=age;
            this.gender=gender;
        }
        Student.prototype=Person.prototype;
        let student=new Student("廣鐵一中","王菲菲",14,"女");
        console.log(Student.prototype===Person.prototype)
        console.log(student.constructor)

缺點:父類的原型對象調用了兩次,沒有必要,而且student實例的構造函數是來自於Person

方式四:組合方式優化

function Parent(name,play){
            this.name=name;
            this.play=play;
        }
        function Child(name,play,age){
            Parent.call(this,name,play);
            this.age=age;
        }
        Child.prototype=Parent.prototype;
        let child=new Child("張三","玩",20);
        let child2=new Child("李四","吃",10)
        console.log(child,child2)
        console.log(child.prototype===child2.prototype); true
        console.log(child.constructor); // 構造函數指向的是Parent

缺點:child實例的構造函數來自於Parent

方式五: 組方式優化

只是這種方式的話,你必須得理解Object.create()方法的使用,他創建的對象是在原型上面的

function Parent(name,play){
            this.name=name;
            this.play=play;
        }
        function Child(name,play,age){
            Parent.call(this,name,play);
            this.age=age;
        }
        Child.prototype=Object.create(Parent.prototype);// 隔離了父類和子類的構造函數,父類的添加到了__proto__屬性上
        Child.prototype.constructor=Child
        let child=new Child("張三","玩",20);
        let child2=new Child("李四","吃",10)
       
        console.log(child.constructor)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM