class的繼承

類的繼承

class ZxxSubFn extends ZxxFn {
    constructor (name, age, salary) {
        super(name, age); // 調用父類的構造方法
        this.salary = salary
    }
    // 父類的方法重寫
    showName () {
        console.log('調用子類的構造方法')
        console.log(this.name, this.salary)
    }
}
let zxx1 = new ZxxSubFn('zxx', 18, 88888888)
console.log(zxx1) // ZxxSubFn {name: "zxx", age: 18, salary: 88888888}
zxx1.showName() // 調用子類的構造方法 zxx 88888888

重複聲明一個類會引起類型錯誤。

class Foo {};
class Foo {}; 
// Uncaught TypeError: Identifier 'Foo' has already been declared

若之前使用類表達式定義了一個類,則再次聲明這個類同樣會引起類型錯誤。

let Foo = class {};
class Foo {}; 
// Uncaught TypeError: Identifier 'Foo' has already been declared

類實質上就是一個函數。類自身指向的就是構造函數。所以可以認爲ES6中的類其實就是構造函數的另外一種寫法!

console.log(typeof ZxxFn); // function
console.log(ZxxFn === ZxxFn.prototype.constructor); // true

子類必須在constructor方法中調用super方法,否則新建實例時會報錯。這是因爲子類自己的this對象,必須先通過父類的構造函數完成塑造,得到與父類同樣的實例屬性和方法,然後再對其進行加工,加上子類自己的實例屬性和方法。如果不調用super方法,子類就得不到this對象。 

class Point { /* ... */ }

class ColorPoint extends Point {
  constructor() {
  }
}

let cp = new ColorPoint(); // ReferenceError

如果子類沒有定義constructor方法,這個方法會被默認添加,代碼如下。也就是說,不管有沒有顯式定義,任何一個子類都有constructor方法。

class ColorPoint extends Point {
}

// 等同於
class ColorPoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

 

在子類的構造函數中,只有調用super之後,纔可以使用this關鍵字,否則會報錯。這是因爲子類實例的構建,基於父類實例,只有super方法才能調用父類實例。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    this.color = color; // ReferenceError
    super(x, y);
    this.color = color; // 正確
  }
}

父類的靜態方法,也會被子類繼承。hello()A類的靜態方法,B繼承A,也繼承了A的靜態方法。

class A {
  static hello() {
    console.log('hello world');
  }
}

class B extends A {
}

B.hello()  // hello world

Object.getPrototypeOf方法可以用來從子類上獲取父類。可以使用這個方法判斷,一個類是否繼承了另一個類。

Object.getPrototypeOf(ColorPoint) === Point
// true

 

 

發佈了228 篇原創文章 · 獲贊 240 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章