1. 程式人生 > >【JavaScript】-繼承

【JavaScript】-繼承

前言

說起繼承,情不自禁的會想起封裝和多型,那我在這裡簡單闡述一下多型和封裝,後面我們重點說JS怎麼實現的繼承。

封裝:可以稱為包裝,一堆重複的程式碼放在一個函式中,用的時候直接調取。一系列類似的方法放在一個物件中。

多型:一個物件有不同的行為,或者同一個行為針對不同的物件,產生不同的結果。

繼承

首先我先說明一點,JavaScript不是一門面向物件的語言,JavaScript是一門基於對相關的語言,JavaScript可以通過建構函式來模擬class來實現。舉個栗子:

    <script>
        //動物有名字,有體重,有吃東西的行為
        //小狗有名字,有體重,有毛色,有吃東西的行為,還有要人的行為
        //哈士奇名字,有體重,有毛色,性別,有吃東西的行為,咬人的行為,逗主人開心的行為

        //動物的建構函式
        function Animal(name,weight) {
            this.name = name;
            this.weight = weight;
        }
        //動物的原型的方法
        Animal.prototype.eat = function () {
            console.log("天天吃東西,就是吃");
        }

        //狗的建構函式
        function Dog(color) {
            this.color = color;
        }
        Dog.prototype = new Animal("哮天犬", "50kg");
        Dog.prototype.bitePerson = function () {
            console.log("汪汪  ~~咬死你");
        };

        //哈士奇
        function ErHa(sex) {
            this.sex = sex;
        }
        ErHa.prototype = new Dog("黑白色");
        ErHa.prototype.playHost = function () {
            console.log("拆家  ...  開心不  ..  驚喜不  ..");
        };

        var erHa = new ErHa("雄性");
        console.log(erHa.name, erHa.weight, erHa.color);
        erHa.eat();
        erHa.bitePerson();
        erHa.playHost();
    </script>

最後的輸出結果為:
在這裡插入圖片描述
解釋一下這個例子:有個動物的建構函式,動物有自己的原型物件。有個狗的建構函式,狗的例項物件改變了指向,指向了動物的原型物件。有個二哈的建構函式,二哈的例項物件指向了狗的例項物件,所以二哈有了所有的方法。是不是和原型很像,沒錯繼承的本質就是原型。

借用建構函式來繼承

    <script>
        function person(name,age,sex,weight) {
            this.name = name;
            this.age = age;
            this.sex = sex;
            this.weight = weight;
        }
        person.prototype.sayhi = function () {
            console.log("您好");
        }
        function student(name,age,sex,weight,score) {
            //借用建構函式
            person.call(this, name, age, sex, weight);
            this.score = score;
        }
        var stu1 = new student("小明", 10, "10kg", "110");
        console.log(stu1.name, stu1.age, stu1.sex, stu1.weight, stu1.score);
        var stu2 = new student("小換", 11, "11kg", "120");
        console.log(stu2.name, stu2.age, stu2.sex, stu2.weight, stu2.score);
        var stu3 = new student("小畫", 12, "12kg", "130");
        console.log(stu3.name, stu3.age, stu3.sex, stu3.weight, stu3.score);
    </script>

借用建構函式實現繼承,主要的程式碼就是:

        function student(name,age,sex,weight,score) {
            //借用建構函式
            person.call(this, name, age, sex, weight);
            this.score = score;
        }

本來student中是沒有name,age,sex,weight這些屬性的。那就需要Call這個方法來‘借’,借過來就是自己了,就可以使用了。但是它有個致命的缺陷就是方法借不過來!那麼就有了組合繼承。

組合繼承

組合繼承=原型繼承+借用建構函式繼承

    <script>
        //組合繼承:原型繼承+借用建構函式繼承

        function person(name,age,sex) {
            this.name = name;
            this. age = age;
            this.sex = sex;
        }
        person.prototype.sayHi = function () {
            console.log("qwer");
        };
        function student(name,age,sex,score) {
            //借用建構函式
            person.call(this, name, age, sex);
            this.score = score;
        }

        //改變原型指向
        student.prototype = new person();
        student.prototype.eat = function () {
            console.log("吃東西");
        };

        var stu = new student("小阿斯頓", 20, "男", "100");
        console.log(stu.name, stu.age, stu.sex, stu.score);
        stu.sayHi();
        stu.eat();
    </script>

執行結果為:
在這裡插入圖片描述
我們通過借構成函式來實現屬性的繼承,通過改變原型的指向來繼承方法。

拷貝繼承

拷貝繼承:那一個物件中的屬性或者方法複製到另一個物件中

	 function person() {
        }
        person.prototype.age = 10;
        person.prototype.sex="男";
        person.prototype.height = 100;
        person.prototype.play = function () {
            console.log("玩得好開心");
        }
        var obj2 = {};

        //person 的構造中有原型prototype,prototype就是一個物件,那麼裡面age,sex,height,play都是改物件中的屬性或者方法

        for (var key in person.prototype) {
            obj2[key] = person.prototype[key];
        }
        console.log(obj2.age, obj2.sex, obj2.height, obj2.play());

改變原型指向是棧裡的兩個物件指向堆裡一個地址。拷貝繼承是在堆裡開闢一個新的空間,兩個物件分別指向自己的地址。

總結

對,沒錯。繼承的本質就是原型。