1. 程式人生 > >【原型和原型鏈】類和繼承

【原型和原型鏈】類和繼承

一、定義“類” ——建構函式

我們知道,JavaScript中沒有類的概念,我們只是通過函式來模仿類的行為,我們將它稱之為建構函式

建構函式分兩類,原生建構函式和自定義建構函式。原生建構函式像Array、Object,是執行環境自動提供的;自定義建構函式是我們自己來建立的

當你想用相同的屬性和方法建立多個相似的物件時,建構函式是非常有用的。

定義建構函式的方法:

function Animal(name){
    //此判斷是使用時預設new關鍵詞時的安全策略
    if(!(this instanceof Animal)){
        return
new Animal(name); } this.name = name; } Animal.prototype = { eat: function(){ console.log('I am eating'); } } var dog = new Animal(); dog.eat(); // I am eating

在呼叫new創造例項時,做了下面幾件事:

  1. 建構函式中的this指向當前出發執行的物件,即dog,所以在dog本身添加了屬性name

  2. dog的__proto__指向Animal的prototype,對dog.__proto__

    中屬性的修改會引起Animal中prototype的變化,從而使得所有由Animal創造的例項__proto__中的屬性改變(引用型別,全都指向同一地址)

  3. dog的constructor屬性指向Animal本身,因為dog的constructor指向Animal本身,所以我們可以通過instanceof來判斷dog是否為Animal的例項,但是constructor可以被改寫,所以通過instanceof來判斷不一定準確

二、繼承

在JavaScript中一切都是物件,當我們談到繼承,其實是物件從物件中的繼承,而不是類從類中的繼承

很多時候我們在建立多個具有相同屬性的例項時,可能有幾個具有自己特有的屬性,所以我們需要先繼承公共建構函式中的屬性,然後改寫自己特有的屬性

繼承寫法:

function Animal(name){
    if(!(this instanceof Animal)){
        return new Animal(name);
    }
    this.name = name;
}

Animal.prototype = {
    eat: function(){
        console.log('I am eating');
    }
}

function Mammalia(name, age){
    this.name = name;
    this.age = age;
}

Mammalia.prototype = new Animal();

var dog = new Mammalia('hashiqi', 5);

最後生成的原型鏈如圖:

這裡寫圖片描述

三、ES6中的class

class一直是 JS 的關鍵字(保留字),但是一直沒有正式使用,在ES6中終於使用到了它,通過class來定義建構函式,從語法上更加符合面向物件的寫法

對目錄一中程式碼的改寫:

class Animal {
    constructor(name){
        this.name = name;
    }

    eat(){
        console.log('I am eating');
    }
}

var dog = new Animal();

dog.eat(); // I am eating

對目錄二繼承程式碼的改寫:

class Animal {
    constructor(name){
        this.name = name;
    }
    eat(){
        console.log('I am eating');
    }
}

class Mammalia extends Animal {
    constructor(name, age){
        super(name);
        this.name = name;
        this.age = age;
    }
}

var dog = new Mammalia('hashiqi', 5);

注意:

  • 子類的constructor一定要執行super(),以呼叫父類的constructor
  • 繼承的關鍵詞是extends,不要忘記s
  • class是ES6提供的一種語法糖,其內部實現原理還是一樣的