首页 > 解决方案 > javascript:扩展的销毁方法不会被调用,但超级会被调用

问题描述

为什么我的扩展类中的destroy方法没有被调用,但我的super destroy方法却被调用了?您能否让我的示例以这种方式工作?

function MyClass(name, age) {
  this.name = name;
  
  this.destroy = function() {
    console.log('Super Class Destroy Method');
  }
  
  if(age == undefined) {
    return null;
  }
  
  return new MyClass2(name, age);
}

class MyClass2 extends MyClass {
  
  constructor(...args) {
    super(args[0]);
    
    this.age = args[1];
  }
  
  destroy() {
    super.destroy();
    
    console.log('Extedned Destroy Method');
  }
}


var myObj = MyClass('John Doe', 9);

myObj.destroy();

标签: javascriptphphtmljquerycss

解决方案


在父类的构造函数中,您可以:

  this.destroy = function() {
    console.log('Super Class Destroy Method');
  }

这会将destroy 方法直接放在实例上。相反,在子类中:

  destroy() {
    super.destroy();
    
    console.log('Extedned Destroy Method');
  }

这个destroy方法在原型上。

这是原型链的样子,对于一个子实例:

instance <- MyClass2.prototype <- MyClass.prototype <- Object.prototype

如果你实例化一个孩子,当你这样做时,父母的构造函数将分配给实例的一个属性this.destroy =,所以super.destroy()不会工作(超类destroy在其原型上没有方法)。

因此,将超类更改destroy为原型上的实际方法。

function MyClass(name, age) {
  this.name = name;

  if (age == undefined) {
    return null;
  }

  return new MyClass2(name, age);
}
MyClass.prototype.destroy = function() {
  console.log('Super Class Destroy Method');
}

class MyClass2 extends MyClass {

  constructor(...args) {
    super(args[0]);

    this.age = args[1];
  }

  destroy() {
    super.destroy();

    console.log('Extedned Destroy Method');
  }
}


var myObj = new MyClass('John Doe', 9);

myObj.destroy();

function虽然同时使用两者和class语法很奇怪,但请考虑使用 justclass代替:

class Parent {
  constructor(name, age) {
    this.name = name;
    return age === undefined ? null : new Child(name, age);
  }
  destroy() {
    console.log('Super Class Destroy Method');
  }
}

class Child extends Parent {
  constructor(...args) {
    super(args[0]);
    this.age = args[1];
  }
  destroy() {
    super.destroy();
    console.log('Extedned Destroy Method');
  }
}

var myObj = new Parent('John Doe', 9);
myObj.destroy();

此外,return null如果没有age传递,则不起作用,因为当您使用 调用函数时,无论如何都会new返回一个对象;仍将返回父级的实例。考虑在验证之前调用一个函数来创建对象,而不是构造函数 - 或者,如果参数无效则抛出错误:return null

class Parent {
  constructor(name, age) {
    this.name = name;
    if (Object.getPrototypeOf(this) === Parent.prototype) {
      // avoid stack overflow
      return new Child(name, age);
    }
  }
  destroy() {
    console.log('Super Class Destroy Method');
  }
}

class Child extends Parent {
  constructor(...args) {
    super(args[0]);
    this.age = args[1];
  }
  destroy() {
    super.destroy();
    console.log('Extedned Destroy Method');
  }
}

const makeParent = (name, age) => age === undefined ? null : new Parent(name, age);
const myObj = makeParent('John Doe', 9);
myObj.destroy();


推荐阅读