es6實現(xiàn)繼承的關(guān)鍵字是什么

本篇內(nèi)容主要講解“es6實現(xiàn)繼承的關(guān)鍵字是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“es6實現(xiàn)繼承的關(guān)鍵字是什么”吧!

成都創(chuàng)新互聯(lián)成都企業(yè)網(wǎng)站建設(shè)服務(wù),提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作網(wǎng)站開發(fā),網(wǎng)站定制,建網(wǎng)站,網(wǎng)站搭建,網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站,網(wǎng)頁設(shè)計師打造企業(yè)風(fēng)格網(wǎng)站,提供周到的售前咨詢和貼心的售后服務(wù)。歡迎咨詢做網(wǎng)站需要多少錢:13518219792

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

ES6 Class 的繼承

1.簡介

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

//父類
class Point {
 ...
}
//子類
class ColorPoint extends Point {
	constructor(x, y, color) {
		super(x, y);
		this.color = color;
	}
	toString() {
		return this.color + '' + super.toString(); // 調(diào)用父類的toString方法
	}
}

上面代碼中,constructor方法和toString方法內(nèi)部,都出現(xiàn)了super關(guān)鍵字,super在這里表示父類的構(gòu)造函數(shù),用來新建一個父類的實例對象。

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

為什么子類的構(gòu)造函數(shù),一定要調(diào)用super()?

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

這意味著,每次新建子類實例時,父類的構(gòu)造函數(shù)必定會先運行一次

class Foo {
	constructor() {
		console.log(1);
	}
}

class Bar extends Foo {
	constructor() {
		super();
		console.log(2);
	}
}

const bar = new Bar(); // 1 2

上面的代碼中,子類Bar新建實例時,會輸出1和2,這就是因子類構(gòu)造函數(shù)調(diào)用super()時,會執(zhí)行一次父類構(gòu)造函數(shù)。只有在子類的構(gòu)造函數(shù)中調(diào)用super之后,才可以使用this關(guān)鍵字,否則會報錯。這是因為子類實例的構(gòu)建,必須先完成父類的繼承,只有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方法,這個方法會默認添加,并且里面會調(diào)用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 調(diào)用父類 Foo 的私有屬性或私有方法,都會報錯。

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

class Foo {
  #p = 1;
  getP() {
    return this.#p;
  }
}

class Bar extends Foo {
  constructor() {
    super();
    console.log(this.getP()); // 1
  }
}

3.靜態(tài)屬性和方法的繼承

父類的靜態(tài)屬性和靜態(tài)方法,也會被子類繼承。

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

class B extends A {
}

B.hello()  // hello world

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

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

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關(guān)鍵字

super關(guān)鍵字既可以當(dāng)做函數(shù)使用,也可以當(dāng)做對象使用

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

class A {
	constructor() {
    console.log(new.target.name);
  }
}

class B extends A {
	constructor() {
		super();
	}
}

new A(); // A
new B(); // B

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

class A {
	p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();

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

由于super指向父類的原型對象,所以定義在父類實例上的方法或?qū)傩裕菬o法通過super調(diào)用的。如下所示:

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規(guī)定,在子類普通方法中通過super調(diào)用父類的方法時,方法內(nèi)部的this指向當(dāng)前的子類實例

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()調(diào)用的是A.prototype.print(),但是此時方法內(nèi)部的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。而當(dāng)讀取super.x 的時候,讀的是A.prototype.x,所以返回undefined。

如果super作為對象,用在靜態(tài)方法之中,這時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在靜態(tài)方法之中指向父類,在普通方法之中指向父類的原型對象。

另外,在子類的靜態(tài)方法中通過super調(diào)用父類的方法時,方法內(nèi)部的this指向當(dāng)前的子類,而不是子類的實例

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

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

到此,相信大家對“es6實現(xiàn)繼承的關(guān)鍵字是什么”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

新聞名稱:es6實現(xiàn)繼承的關(guān)鍵字是什么
網(wǎng)頁鏈接:http://muchs.cn/article42/jcpjhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)、網(wǎng)站營銷、域名注冊、企業(yè)網(wǎng)站制作、企業(yè)建站、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)