秋招复习计划-ES6知识点1

  |  

前言

ES6中super指向的问题。super.function、super.attribute和super()分别指向什么,傻傻分不清楚


54



super()

众所周知,在ES6中,如果我们想使用class来实现继承,子类就必须在构造函数constructor中调用super()方法,否则新建实例时就会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。所以我们需要super()函数在子类中初始化this,并继承父类的属性。

1
2
3
4
5
6
7
8
9
10
11
12
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A(); // A
new B(); // B

虽然super代表父类A的构造函数,但是返回的是子类B的实例,及super内部的this指向的是B的实例,因此这里的super相等于

1
A.prototype.constructor.call(this);

作为函数时,super()只能在子类的构造函数中使用,用在其它地方只会报错

super.function

当super作为对象,并调用它的方法时,super在普通方法(包括构造方法)中,指向父类的原型对象,在静态方法中,指向父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);
// 在子类的静态方法中,super指向父类
}
myMethod(msg) {
super.myMethod(msg);
// 在普通方法中,super指向的是父类的原型对象
}
}

同时ES6规定,通过super调用父类的方法时,无论是静态方法还是普通方法,super会绑定子类的this。

super.attribute

当我们通过super对某一属性进行赋值时,super就是当前类的this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();

上面的代码中,super.x赋值为3,这时等同于对this.x赋值为3。而当读取suepr.x的时候,读取的是A.prototype.x,所以返回undefined。

对于这个问题我的理解是,当使用super调用父类的方法时,方法内部的this绑定的是子类的this,那么方法内部的this本就指向调用方法的对象,所以

1
2
3
方法内部的this -> super
方法内部的this绑定为子类的实例
super -> 子类实例

而这种指向关系只有在赋值的时候才具备。而当我们读取属性的时候super就是父类的原型。

虽然我并不知道具体的底层是不是这样转换的,但是我只能通过这种方式来理解记忆。不过在平常的程序编写中也不会用super来访问子类实例的属性。

文章目录
  1. 1. super()
  2. 2. super.function
  3. 3. super.attribute