JavaScript中super关键词的必要性

super关键词

JS中super关键词是用来调用原型对象的属性和方法的,本文分析使用super关键词的必要性

this指向导致的原型调用问题

JS中存在多种”this绑定“方式,最核心的就是”调用绑定“,即xxx.show(),那么show方法中的this就指向xxx。

如果直接show(),那么实际上在浏览器中是window.show(),this就指向window。

通常this绑定在基于原型链的方法调用下是没有问题的,无论调用的方法是否来自于原型。
但是,在继承的场景下,如果需要手动调用原型方法,比如this.__proto__.show(),那么show方法中的this就会指向this.proto,即原型对象自己。

const person = {
  name: "person.name",
  show() {
    console.log(this.name);
  },
};
const user = {
  __proto__: person,
  name: "user.name",
  show() {
    // person.name  由于此时原型对象中的this是原型自己(this.__proto__)
    this.__proto__.show();
  },
};
user.show();

这里就会产生冲突,因为我们希望即便手动调用原型,this的指向仍然是对象本身而不是原型。

super关键字就可以解决这种问题,既可以调用原型方法同时又不改变this指向。

通过call方法解决this指向问题

当然我们可以使用call方法重新定义this指向。

const person = {
  name: "person.name",
  show() {
    console.log(this.name);
  },
};
const user = {
  __proto__: person,
  name: "user.name",
  show() {
    // 使用call方法重新定义this指向
    this.__proto__.show.call(this)
  },
};
user.show();

但是this.__proto__.show.call()在多级继承中就不生效了。

const person = {
  name: "person.name",
  show() {
    console.log(this.name);
  },
};
const user = {
  __proto__: person,
  name: "user.name",
  show() {
    // 多级继承时,由于this始终指向admin,则this.__proto__指向user而不是person
    // this.__proto__.show.call(this)
    // 当然可以为了admin.show()手动调整,但显然这样做的适应性很差
    // 如果user.show()则会报错
    // this.__proto__.__proto__.show.call(this)
  },
};
const admin = {
  __proto__: user,
  name: "admin.name",
  show() {
    this.__proto__.show.call(this)
  }
}
admin.show();

所以,手动修改this的指向既繁琐又不灵活,JS于是提供了super关键词实现这些功能。

posted @ 2020-06-11 14:43  Peterer~王勇  阅读(595)  评论(0编辑  收藏  举报