站長資訊網
最全最豐富的資訊網站

es6中用什么實現繼承

es6中用class和extends關鍵字來實現繼承。ES6中引入了class關鍵字來聲明類, 而class(類)可通過extends關鍵字實現繼承,讓子類繼承父類的屬性和方法,語法“class 父類名{…} class 子類名 extends 父類名{…};”。

es6中用什么實現繼承

本教程操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

es6中可利用class關鍵字配合extends關鍵字來實現繼承。

ES6 Class 的繼承

1.簡介

Class可以通過extends關鍵字實現繼承,讓子類繼承父類的屬性和方法。這比 ES5 的通過修改原型鏈實現繼承,要清晰和方便很多。

//父類 class Point {  ... } //子類 class ColorPoint extends Point { 	constructor(x, y, color) { 		super(x, y); 		this.color = color; 	} 	toString() { 		return this.color + '' + super.toString(); // 調用父類的toString方法 	} }
登錄后復制

上面代碼中,constructor方法和toString方法內部,都出現了super關鍵字,super在這里表示父類的構造函數,用來新建一個父類的實例對象。

ES6規定,子類必須在constructor方法中調用super(),否則會報錯,這是因為子類自己的this對象,必須先通過父類的構造函數完成塑造,得到與父類同樣的實例屬性和方法,然后在添加子類自己的實例屬性和方法。

為什么子類的構造函數,一定要調用super()?

這是因為在ES5的繼承機制中,是先創造一個獨立的子類的實例對象,然后再將父類的方法添加到這個對象上,即“實例在前,繼承在后”;ES6的繼承機制,則是先將父類的屬性和方法,加到一個空的對象上面,然后再將該對象作為子類的實例,即“繼承在前,實例在后”。

這意味著,每次新建子類實例時,父類的構造函數必定會先運行一次

class Foo { 	constructor() { 		console.log(1); 	} }  class Bar extends Foo { 	constructor() { 		super(); 		console.log(2); 	} }  const bar = new Bar(); // 1 2
登錄后復制

上面的代碼中,子類Bar新建實例時,會輸出1和2,這就是因子類構造函數調用super()時,會執行一次父類構造函數。只有在子類的構造函數中調用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; 		super(x, y); 		this.color = color; 	} }"
登錄后復制

如果子類沒有定義constructor方法,這個方法會默認添加,并且里面會調用super,也就是說,不管有沒有顯示定義,任何一個子類都有constructor方法.

class Point {   constructor(x, y) {     this.x = x;     this.y = y;   } } class ColorPoint extends Point { }  let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8}  class ColorPoint extends Point {   constructor(...args) {     super(...args);   } }  let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8}
登錄后復制

2.私有屬性和私有方法的繼承

父類所有的屬性和方法,都會被子類繼承,除了私有的屬性和方法。子類無法繼承父類的私有屬性,或者說私有屬性只能在定義它的class里面使用。

class Foo {   #p = 1;   #m() {     console.log('hello');   } }  class Bar extends Foo {   constructor() {     super();     console.log(this.#p); // 報錯     this.#m(); // 報錯   } }
登錄后復制

上面示例中,子類 Bar 調用父類 Foo 的私有屬性或私有方法,都會報錯。

如果父類定義了私有屬性的讀寫方法,子類就可以通過這些方法,讀寫私有屬性。

class Foo {   #p = 1;   getP() {     return this.#p;   } }  class Bar extends Foo {   constructor() {     super();     console.log(this.getP()); // 1   } }
登錄后復制

3.靜態屬性和方法的繼承

父類的靜態屬性和靜態方法,也會被子類繼承。

class A {   static hello() {     console.log('hello world');   } }  class B extends A { }  B.hello()  // hello world
登錄后復制

上面代碼中,hello()A類的靜態方法,B繼承A,也繼承了A的靜態方法。

注意,靜態屬性是通過淺拷貝實現繼承的,如果繼承的屬性是原始數據類型,子類中操作繼承的靜態屬性不會影響到父類,但如果繼承的屬性是一個對象,那么子類修改這個屬性會印象到父類

class C { 	static foo = 100; }  class D extends C { 	constructor() { 		super(); 		D.foo--; 	} }  const d = new D(); C.foo; // 100 D.foo;  // 99  class A { 	static foo = { n: 100 }; }  class B extends A { 	constructor() { 		super(); 		B.foo.n--; 	} }  const b = new B(); B.foo.n // 99 A.foo.n  // 99
登錄后復制

4.Object.getPrototypeOf()

Object.getPrototypeOf()方法可以用來從子類上獲取父類。

class Point { /*...*/ }  class ColorPoint extends Point { /*...*/ }  Object.getPrototypeOf(ColorPoint) === Point // true
登錄后復制

因此,可以使用這個方法判斷,一個類是否繼承了另一個類。

5.super關鍵字

super關鍵字既可以當做函數使用,也可以當做對象使用

第一種情況,super作為函數調用時,代表父類的構造函數。調用super的作用是形成子類的this對象,把父類的實例屬性和方法都放到這個this對象上面。

class A { 	constructor() {     console.log(new.target.name);   } }  class B extends A { 	constructor() { 		super(); 	} }  new A(); // A new B(); // B
登錄后復制

第二種情況,super作為對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類。

class A { 	p() {     return 2;   } }  class B extends A {   constructor() {     super();     console.log(super.p()); // 2   } }  let b = new B();
登錄后復制

上面代碼中,子類B中的super.p(),將super當做一個對象使用,這時super在普通對象中,指向的是A.prototype,super.p()相當于A.prototype.p()。

由于super指向父類的原型對象,所以定義在父類實例上的方法或屬性,是無法通過super調用的。如下所示:

class A { 	constructor() { 		this.p = 2; 	} }  class B extends A { 	get m() { 		return spuer.p; 	} }  let b = new B(); b.m // undefined
登錄后復制

為了解決這種問題,可以將屬性定義在父類的原型對象上

class A {}; A.prototype.x = 2;  class B extends A { 	constructor() { 		super(); 		console.log(super.x); 	} }  let b = new B();
登錄后復制

ES6規定,在子類普通方法中通過super調用父類的方法時,方法內部的this指向當前的子類實例

class A { 	constructor() { 		this.x = 1; 	} 	print() { 		console.log(this.x); 	} }  class B extends A { 	constructor() { 		super(); 		this.x = 2; 	} 	m() { 		super.print(); 	} }  let b = new B(); b.m(); // 2
登錄后復制

上面代碼中,super.print()調用的是A.prototype.print(),但是此時方法內部的this指向是子類B的實例,所以輸出2。

由于this指向的是子類實例,所有如果通過super對某個屬性賦值,這時super就是this,賦值的屬性會變成子類實例的屬性

class A { 	constructor() { 		this.x = 1; 	} }  class B extends A { 	constructor() { 		super(); 		this.x = 2; 		super.x = 3; 		console.log(super.x); //undefind 		console.log(this.x); // 3 	} }
登錄后復制

上面代碼中,super.x賦值為3,這時等同于對this.x賦值為3。而當讀取super.x 的時候,讀的是A.prototype.x,所以返回undefined。

如果super作為對象,用在靜態方法之中,這時super將指向父類,而不是父類的原型對象。

class Parent { 	static myMethod(msg) { 		console.log('static', msg); 	}  	myMethod(msg) { 		console.log('instance', msg); 	} }  class Children extends Parent { 	static myMethod(msg) { 		super.myMthod(msg); 	}  	myMethod(msg) {     super.myMethod(msg);   } }  Child.myMethod(1); // static 1  var child = new Child(); child.myMethod(2); // instance 2
登錄后復制

上面代碼中,super在靜態方法之中指向父類,在普通方法之中指向父類的原型對象。

另外,在子類的靜態方法中通過super調用父類的方法時,方法內部的this指向當前的子類,而不是子類的實例

class A { 	constructor() {     this.x = 1;   }   static print() {     console.log(this.x);   } }  class B extends A {   constructor() {     super();     this.x = 2;   }   static m() {     super.print();   } }  B.x = 3; B.m() // 3
登錄后復制

在靜態方法m中,super.print指向父類的靜態方法,到那時this指向的是類B,而不是B的實例。

【推薦學習:javascript高級教程】

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
日韩视频在线观看免费| 久久国产精品老人性| 国产成人精品视频午夜| 97精品国产一区二区三区| 久久久久久久久毛片精品| 中文字幕日韩精品无码内射| 亚洲AⅤ永久无码精品AA| 日韩一区二区视频在线观看| 国产精品情侣呻吟对白视频| 一本色道久久88—综合亚洲精品 | 国产成人综合一区精品| 51视频精品全部免费最新| 久久精品人人做人人爽| 精品国内片67194| 91麻豆精品国产自产在线观看一区| mm1313亚洲精品无码又大又粗| 亚洲AV日韩AV天堂一区二区三区 | 91精品国产色综合久久| 国产精品成人99久久久久| 狠狠综合视频精品播放| 日韩精品无码一本二本三本| 国产91成人精品亚洲精品| 国产精品嫩草影院在线| 精品剧情v国产在线麻豆| 亚洲国产精品99久久久久久| 国产精品玖玖玖在线观看| 无码国产精品一区二区免费式影视| 中文字幕色婷婷在线精品中| 亚洲综合一区二区精品久久| 亚洲精品国产专区91在线| 5x社区精品视频在线播放18| 日本aⅴ精品中文字幕| 99精品视频在线视频免费观看| 午夜精品视频在线| 欧洲精品99毛片免费高清观看| 亚洲国产精品热久久| 久久亚洲中文字幕精品有坂深雪 | 日韩蜜芽精品视频在线观看| 国产乱子伦精品免费女| 国产精品一区二区三区高清在线| 国产精品美女久久久网站|