【问题标题】:javascript: Extened destroy method doesn't get called but super does get calledjavascript:不会调用扩展的销毁方法,但会调用超级方法
【发布时间】:2020-09-28 02:38:23
【问题描述】:

为什么我的扩展类中的 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();

【问题讨论】:

    标签: javascript php html jquery css


    【解决方案1】:

    在父类的构造函数中,你这样做:

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

    这会将销毁方法直接放在实例上。相比之下,在子类中:

      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();

    不过,同时使用 functionclass 语法很奇怪,请考虑只使用 class

    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();

    【讨论】:

    • 我这样构建它的原因是如果年龄参数不存在则返回 null 所以我没有使用 new 关键字,你可以将你的代码重构为像我的一样并返回 null if那个参数不存在
    • 我测试了你的代码,如果年龄不存在,它不会返回 null
    • 哦,我明白了,return null(在我们的两个代码中)根本不起作用,因为您正在使用 new 调用,它必须返回一个对象。要么不要用new调用函数,要么返回一个空对象
    • 您的示例有效,但由于 destroy 方法,我仍然最终将代码加倍,我的意思是我可以在一个简单的类函数的构造函数中返回 null 而无需使用 new 关键字和然后调用扩展类,但是当我想返回 null 时,destory 方法是问题所在。你明白我的意思吗。你能换个方式吗
    • destroy 方法实际上是做什么的?每个子类都需要它似乎很奇怪——只要把它放在父类上,如果可行的话,我会这样做。可能返回 nullmakeParent 工厂函数是完全独立的
    猜你喜欢
    • 2018-03-18
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 2011-12-07
    • 2017-05-22
    相关资源
    最近更新 更多