(八) class中的继承
class中的继承
extends 关键字
class Father { }
class Son extends Father { }
super 关键字
super既可以当作函数又可以当作对象
1. 当作函数使用时
先来看一个示例, A继承自B, 然后直接实例化A
class B { }
class A extends B {
constructor() {
console.log(this)
}
}
new A()
// Must call super constructor in derived class before accessing 'this' or returning from derived
// constructor
// 在访问“this”或从派生构造函数返回之前,必须在派生类中调用超级构造函数
**报错了 ! ** 从错误中很容易看出, 我们要先在子类中调用super()
函数, 才能访问this
,这也是ES6的规定
super
当函数使用时, 规定只能在子类的constructor
中使用, 且必须写在constructor
开头第一行
这是因为当使用extends
继承时, 子类是没有this
对象的, 而是继承父类的this
对象, 并对其进行一些加工, 而super()
函数就是来做这件事的,
- @记住: 使用extends继承必须在子类构造函数的第一行调用super()函数, 且只能在子类构造函数中使用
class B { }
class A extends B {
constructor() {
super()
console.log(this)
}
}
new A() // A {}
而且, 当通过调用super()
来继承父类的this
时, 会调用父类的constructor
方法, 并为子类返回一个this
, 该this
指向的是子类的实例
示例 => 验证调用super()后的this指向子类的实例
class A {
info = "我是父类的实例属性"
print() {
console.log(this.info)
}
}
class B extends A {
info = "我是子类的实例属性"
constructor() {
super()
}
m() {
// super当对象使用, 介绍在下面
super.print()
}
}
let b = new B()
b.m() // 我是子类的实例属性
2. 当作对象使用时
2.1 在普通方法中
super (没有小括号, 表示对象) 在普通方法中, 指向父类的原型对象
- 直接在类内部定义的方法都是定义在原型上的
- 直接定义在类内部的属性是实例属性
示例 1
class Father {
name = 'father'
say() {
console.log('我是父类原型上的方法')
}
}
class Son extends Father {
constructor() {
super()
console.log(super.name) // undefined
super.say() // 我是父类原型上的方法
}
}
new Son()
通过super对子类属性赋值时, super相当于子类实例里面的this
示例 2
class A {
constructor() {
this.x = 1
}
}
class B extends A {
constructor() {
super()
console.log(this.x) // 1 调用super后, 自动调用父类的构造函数
this.x = 2
super.x = 3 // 相当于this.x = 3
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
new B()
2.2 在静态方法中
此时super将指向父类, 而不是父类的原型
- 静态方法/属性又称为类方法/属性, 通过类名.方法名/属性名的方式调用
示例 3
class Father {
static name = '我是父类的属性'
say() {
console.log('我是父类原型上的方法')
}
}
class Son extends Father {
constructor() {
super()
}
static show() {
console.log(super.name) // 我是父类的属性
super.say() // .say is not a function, 因为say是父类原型上的方法
}
}
Son.show()
巩固例子
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child(); child.myMethod(2); // instance 2
在子类静态方法中通过super调用父类方法时, , super相当于子类实例里面的this
class Father {
constructor() {
this.name = 'father'
}
static say() {
console.log(this.name)
}
}
class Son extends Father {
static name = '我是子类的属性'
constructor() {
super()
this.name = 'son'
}
static show() {
super.say()
}
}
Son.show() // 我是子类的属性
仅记录自己的学习总结,如有错误,还请评论指正~