中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

原生Javascript如何實現繼承

發布時間:2021-07-21 14:57:43 來源:億速云 閱讀:123 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關原生Javascript如何實現繼承,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

    前言

    最近在復習javascript的一些基礎知識,為開啟新的征程做準備。所以開始記錄一些自己學習的內容。

    廢話少說,上代碼!

    首先是我們的父類代碼。

    在這里我們創建一個Person的類作為父類,它的構造函數需要2個參數name和age。

    然后我們在它的原型上添加一個sayHi的方法。

    //父類
    function Person (name, age) {
        this.name = name || 'no name';
        this.age = age || 0;
    }
    
    Person.prototype.sayHi = function () {
        console.log('Hi, I\'m ' + this.name + ' and i\'m ' + this.age + ' years old!');
    }
    
    var p = new Person('A',20);
    p.sayHi();//Hi, I'm A and i'm 20 years old!

    原型繼承

    //原型繼承
    function Teacher(){
    }
    
    Teacher.prototype=new Person('B',22);
    Teacher.prototype.constructor=Teacher;
    
    var t = new Teacher();
    t.sayHi();//Hi, I'm B and i'm 22 years old!
    console.log(t instanceof Person);//true
    console.log(t instanceof Teacher);//true

    優點

    從上面的代碼來看,Teacher 的實例擁有了 Person 的屬性和方法。并且實例對象既是 Person的實例也是 Teacher的實例。而且這種繼承方式特別的簡單。

    缺點

    我們可以很容易的就發現Teacher類的 name和 age是固定的,都是name=B和age=22,換句話說就是我們無法實現按照我們的意愿給父類的構造函數傳參。并且一個我們不能給一個 Teacher 指定多個原型,也就是沒法 多繼承。然后我們看下下面這段代碼:

    var t1 = new Teacher();
    var t2 = new Teacher();
    Teacher.prototype.name = "C";
    t1.sayHi();//Hi, I'm C and i'm 22 years old!
    t2.sayHi();//Hi, I'm C and i'm 22 years old!

    上面這段代碼中我們可以看到當原型中的屬性或者方法被改變時,所有的子類實例的屬性和方法也會跟著被改變,也就是原型繼承的另一個缺點:所有子類共享同一個原型對象

    這里說到了原型,我很早之前也寫過一個關于原型的隨筆,不過可能也是有些模糊,現在的理解和當時有所不同,我會在后面重新寫一篇關于原型的隨筆。(寫好了我會附上連接)

    構造函數繼承

    //構造函數繼承
    function Teacher (name, age) {
        Person.call(this, name, age);
    }
    
    var t1 = new Teacher('B', 22);
    var t2 = new Teacher('C', 30);
    console.log(t1.name);//B
    console.log(t2.name);//C
    console.log(t1 instanceof Person);//false
    console.log(t1 instanceof Teacher);//true
    t1.sayHi();//TypeError: t1.sayHi is not a function
    t2.sayHi();//TypeError: t1.sayHi is not a function

    優點

    相對于 原型繼承 , 構造函數繼承解決了所有的子類實例共享統一原型的問題,也可以給父類的構造函數傳參,并且我們可以在子類的構造函數中調用多個父類的構造函數,實現所謂的多繼承(這里的多繼承是指子類通過call,apply等方法去調用父類的構造函數使其擁有父類的屬性和方法,但是js中一個函數對象只存在一個 prototype,所以其實我們沒法通過原型鏈的形式去體現出多繼承)

    缺點

    上面的代碼中我們可以看出創建的實例只是 子類的實例 并不是 父類的實例 ,不能直觀的體現出繼承,這種繼承方式也無法繼承父類的原型上的屬性和方法。

    組合式繼承

    //組合式繼承
    function Teacher (name, age) {
        Person.call(this, name, age);
    }
    
    Teacher.prototype = new Person();
    Teacher.prototype.constructor = Teacher;
    
    
    var t1 = new Teacher('B', 22);
    var t2 = new Teacher('C', 30);
    Teacher.prototype.name = "D";
    console.log(t1.name);//B
    console.log(t2.name);//C
    t1.sayHi();//Hi, I'm B and i'm 22 years old!
    t2.sayHi();//Hi, I'm C and i'm 30 years old!
    console.log(t1 instanceof Person);//true
    console.log(t1 instanceof Teacher);//true

    組合式繼承就是結合了原型繼承和構造函數繼承的優點,解決了兩種方式存在的一些缺點。但是我們會發現每當我們去創建一個子類實例的時候都會去創建一個父類的實例,盡管父類實例不是同一個實例(內存地址不一樣),但是他們其實屬性和方法上完全一致,所以我們通過下面這種(寄生式組合繼承)方式完善它,以避免不必要的實例構造。

    寄生式組合繼承

    //寄生式組合繼承
    function Teacher (name, age) {
        Person.call(this, name, age);
    }
    
    Teacher.prototype = Object.create(Person.prototype);
    Teacher.prototype.constructor = Teacher;
    
    
    var t1 = new Teacher('B', 22);
    var t2 = new Teacher('C', 30);
    Teacher.prototype.name = "D";
    console.log(t1.name);//B
    console.log(t2.name);//C
    t1.sayHi();//Hi, I'm B and i'm 22 years old!  
    t2.sayHi();//Hi, I'm C and i'm 30 years old!
    console.log(t1 instanceof Person);//true
    console.log(t1 instanceof Teacher);//true

    上面的方式解決了我們沒創建一個子類實例都去創建一個父類實例的問題,這也是最為常用的一種js的繼承方式,如果我們通過Babel去把ES6中的class的繼承轉成ES5的代碼,我們會發現就是用的寄生式組合繼承。

    關于“原生Javascript如何實現繼承”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    清远市| 临潭县| 五家渠市| 富顺县| 沙湾县| 平罗县| 图木舒克市| 水富县| 潢川县| 康保县| 昌都县| 寻乌县| 虹口区| 宜宾县| 安图县| 灵宝市| 八宿县| 砚山县| 察哈| 承德县| 徐汇区| 淮北市| 舞阳县| 灵山县| 上林县| 武穴市| 益阳市| 来宾市| 张家港市| 靖安县| 孟津县| 闵行区| 高雄市| 淅川县| 五寨县| 博乐市| 原阳县| 商都县| 连州市| 英吉沙县| 桐乡市|