JS6-Class的繼承

來源:互聯網
上載者:User

標籤:int()   自己   實現繼承   ror   cti   script   ons   函數調用   const   

====繼承

Class 可以通過extends關鍵字實現繼承

class Point {

}

class ColorPoint extends Point {

}

 

上面代碼定義了一個ColorPoint類,該類通過extends關鍵字,繼承了Point類的所有屬性和方法。但是由於沒有部署任何代碼,所以這兩個類完全一樣,等於複製了一個Point類。下面,我們在ColorPoint內部加上代碼。

class Point{

          constructor(x,y){

                    this.x=x

                    this.y=y

                    }

         }

 

class ColorPoint extends Point {

  constructor(x, y, color) {

    super(x, y); // 調用父類的constructor(x, y)

    this.color = color;

  }

 

  toString() {

return this.color

  }

}

上面代碼中,constructor方法之中,都出現了super關鍵字,它在這裡表示父類的建構函式,用來建立父類的this對象。

子類必須在constructor方法中調用super方法,否則建立執行個體時會報錯。這是因為子類沒有自己的this對象,而是繼承父類的this對象,然後對其進行加工。如果不調用super方法,子類就得不到this對象。

class Point { /* ... */ }

class ColorPoint extends Point {

  constructor() {

  }

}

let cp = new ColorPoint(); // ReferenceError

 

 

 

 

ES6 的繼承機制實質是先創造父類的執行個體對象this(所以必須先調用super方法),然後再用子類的建構函式修改this。

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

class Point {

  constructor(x, y) {

    this.x = x;

    this.y = y;

  }

}

class ColorPoint extends Point {

   /*隱式的有:

constructor(x, y) {

  Super(x,y)

    this.x = x;

    this.y = y;

  }

  */

   Myf(){console.log(this.x)}

}

 

 

在子類的建構函式中,只有調用super之後,才可以使用this關鍵字,否則會報錯。

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; // 正確

  }

}

 

 

 

====super 關鍵字

super作為函數調用時,代表父類的建構函式。ES6 要求,子類的建構函式必須執行一次super函數。

class A {}

class B extends A {

  constructor() {

    super();

  }

}

上面代碼中,子類B的建構函式之中的super(),代表調用父類的建構函式。這是必須的,否則 JavaScript 引擎會報錯。

 

 

super()只能用在子類的建構函式之中,用在其他地方就會報錯。

class A {}

class B extends A {

  m() {

    super(); // 報錯

  }

}

 

 

類的 prototype 屬性和__proto__屬性

大多數瀏覽器的 ES5 實現之中,每一個對象都有__proto__屬性,指向對應的建構函式的prototype屬性。Class 作為建構函式的文法糖,同時有prototype屬性和__proto__屬性

(1)子類的__proto__屬性,表示建構函式的繼承,總是指向父類。

(2)子類prototype屬性的__proto__屬性,表示方法的繼承,總是指向父類的prototype屬性。

class A {

}

class B extends A {

}

B.__proto__ === A // true

B.prototype.__proto__ === A.prototype // true

可以這樣理解:作為一個對象,子類(B)的原型(__proto__屬性)是父類(A);作為一個建構函式,子類(B)的原型(prototype屬性)是父類的執行個體。

 

執行個體的 __proto__ 屬性

子類執行個體的__proto__屬性的__proto__屬性,指向父類執行個體的__proto__屬性。也就是說,子類的原型的原型,是父類的原型。

var p1 = new Point(2, 3);

var p2 = new ColorPoint(2, 3, ‘red‘);

p2.__proto__ === p1.__proto__ // false

p2.__proto__.__proto__ === p1.__proto__ // true

ColorPoint繼承了Point,導致前者原型的原型是後者的原型。

因此,通過子類執行個體的__proto__.__proto__屬性,可以修改父類執行個體的行為。

p2.__proto__.__proto__.printName = function () {

  console.log(‘Ha‘);

};

p1.printName() // "Ha"

上面代碼在ColorPoint的執行個體p2上向Point類添加方法,結果影響到了Point的執行個體p1。

 

 

 

原生建構函式的繼承

原生建構函式是指語言內建的建構函式,通常用來產生資料結構。

ES6 允許繼承原生建構函式定義子類,因為 ES6 是先建立父類的執行個體對象this,然後再用子類的建構函式修飾this,使得父類的所有行為都可以繼承。下面是一個繼承Array的例子。

class MyArray extends Array {

  constructor(...args) {

    super(...args);

  }

}

var arr = new MyArray();

arr[0] = 12;

arr.length // 1

上面代碼定義了一個MyArray類,繼承了Array建構函式,因此就可以從MyArray產生數組的執行個體。這意味著,ES6 可以自訂原生資料結構(比如Array、String等)的子類,這是 ES5 無法做到的。

 

JS6-Class的繼承

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.