子類通過extends
關鍵字繼承父類颖对。
class Par{
constructor(){
this.num=21;
}
}
class Chil extends Par{
constructor(){
//繼承父類的構造函數(shù)constructor
super() //這里必須寫,否則下面實例會報錯吉嫩。
}
}
var p=new Chil();
console.dir(p.num) //21
注意:子類必須在constructor
方法中調用super
方法价认,否則新建實例時會報錯。這是因為子類實例的構建自娩,基于父類實例用踩,只有super方法才能調用父類實例。
ES5 繼承和ES6 繼承對比
- ES5 的繼承機制:是先創(chuàng)造子類的實例對象
this
忙迁,然后再將父類的方法添加到this
上面(Parent.apply(this))脐彩。 - ES6 的繼承機制:是先將父類實例對象的屬性和方法,加到
this
上面(所以必須先調用super
方法)姊扔,然后再用子類的構造函數(shù)修改this
序攘。
super關鍵字
1.可以當函數(shù)用酒唉。
super作為函數(shù)調用時,代表父類的構造函數(shù)画恰。
class A {}
class B extends A {
constructor() {
super();
}
}
注意:
-
super
雖然代表了父類A的構造函數(shù)证九,但是返回的是子類B的實例删豺,即super
內部的this
指的是B的實例,因此super()
在這里相當于A.prototype.constructor.call(this)
愧怜。 -
super
只能用在子類的constructor
中呀页。
2.可以作為對象使用。
super
作為對象使用時, 在普通的方法中拥坛,指向的是父類的原型對象蓬蝶。在靜態(tài)方法中,指向的是父類猜惋。
class A {
constructor() {
// 這里是實例上的屬性
this.p = 1;
}
// 普通方法丸氛,放在A原型上的。
say(){
console.log("普通方法")
}
// 靜態(tài)方法著摔,能被子類繼承缓窜,但是不能被實例化對象繼承。
static greeting(){
console.log("靜態(tài)方法")
}
}
// 靜態(tài)屬性
A.age=22;
class B extends A {
constructor(){
super();
}
bsay(){
// p是實例的屬性谍咆,通過this訪問
console.log(this.p) //1
// 在普通方法中禾锤,super指向的是父類原型對象,即prototype摹察,
// 所以能訪問父類原型上的方法恩掷。
super.say() // "普通方法";
}
static bgreeting(){
// 在靜態(tài)方法中,super指向的是父類供嚎,能訪問父類的靜態(tài)屬性和靜態(tài)方法黄娘。
super.greeting(); //"靜態(tài)方法"
console.log(super.age); //22
}
}
let xiao = new B();
xiao.bsay();
B.bgreeting();
要點總結:
- 靜態(tài)方法峭状,能被子類繼承,不能被實例對象繼承寸宏。
- 因為普通方法中宁炫,
super
指向的是父類原型對象。所以子類中氮凝,通過super
只能訪問到父類原型上的方法羔巢。 - 在靜態(tài)方法中,
super
指向的是父類罩阵,只能訪問父類的靜態(tài)屬性和靜態(tài)方法竿秆。 - 普通方法中,
this
指向的是當前類的實例對象稿壁。 - 靜態(tài)方法中幽钢,
this
指向的是當前類。
類的 prototype 屬性和proto屬性
類同時有prototype
屬性和__proto__
屬性傅是,因此同時存在兩條繼承鏈匪燕。
例子:
class Par{
constructor(){
// ....
}
say(){
console.log("我今年"+this.age+"歲了!")
}
static greeting(){
console.log("hello")
}
}
Par.num=101;
class Chil extends Par{
constructor(){
super()
}
}
console.dir(Chil)
- 子類的
__proto__
屬性 ,指向父類喧笔。
即Chil.__proto__ === Par
image.png
-
子類
prototype
屬性的__proto__
屬性帽驯,指向父類的prototype
屬性。
即Chil.prototype.__proto__ === Par.prototype
image.png 子類實例的
__proto__
屬性的__proto__
屬性书闸,指向父類實例的__proto__
屬性尼变。也就是說,子類的原型的原型浆劲,是父類的原型嫌术。
即Chil.__proto__.__proto__ === Par.__proto__
原生構造函數(shù)繼承
Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()
ES5 是先新建子類的實例對象this,再將父類的屬性添加到子類上牌借,由于父類的內部屬性無法獲取度气,導致無法繼承原生的構造函數(shù)。
ES6 允許繼承原生構造函數(shù)定義子類走哺,因為 ES6 是先新建父類的實例對象this蚯嫌,然后再用子類的構造函數(shù)修飾this,使得父類的所有行為都可以繼承丙躏。
class MyArray extends Array {
constructor(...args) {
super(...args);
}
}
var arr = new MyArray();
arr[0] = 12;
arr.length // 1
arr.length = 0;
arr[0] // undefined