【问题标题】:Issue calling a method of class using this when function is called using super当使用 super 调用函数时,使用 this 调用类的方法
【发布时间】:2016-11-09 21:27:38
【问题描述】:
class Dog {
  bark () {
    console.log(`Dog.bark`)
  }
  callMyBark () {
    // how do I have this function use the bark above and not Pug.bark?
    this.bark()
  }
}

class Pug extends Dog {
  bark () {
    console.log(`Pug.bark`)
  }
  callMyBark () {
    super.callMyBark()
  }
}

let pug = new Pug()

pug.callMyBark()

上面的代码记录Pug.bark,预期的行为是记录Dog.bark。我怎样才能让Dog.callMyBark 方法运行Dog.bark

【问题讨论】:

  • 动态调用方法的重点是允许它们被覆盖?
  • 如果您不希望bark 以标准的OO 类方式被覆盖,也许您应该重新考虑如何调用该函数?你能把它作为一个助手完全从课堂上移走,然后从两个地方调用这个助手吗?

标签: node.js class ecmascript-6 babeljs


【解决方案1】:

有几种方法可以做到这一点,但我认为最好的方法是调用super 方法或者根本不覆盖:

class Pug extends Dog {
  bark () {
    super.bark(); // or omit the method entirely
  }

  callMyBark () {
    super.callMyBark()
  }
}

显然这并没有考虑到你从哪里打电话,这似乎是你想要决定的方式。

请记住,在大多数 OO 语言中,像这样基于调用者选择方法是一种反模式,并且已经做了很多工作来避免意外这样做(这是 C++ 中的一个问题,这也是为什么后来的语言的一部分默认为虚拟调度)。

如果您确实需要,我强烈建议您制作函数 static 或一些分离的助手并直接调用它:

class Dog {
  static bark() {
    console.log(`Dog.bark`)
  }

  callMyBark () {
    // how do I have this function use the bark above and not Pug.bark?
    Dog.bark()
  }
}

如果在函数内需要this,可以将实例传递给helper,也可以通过原型(或实例的原型链)调用:

class Dog {
  bark() {
    console.log(`Dog.bark`)
  }

  callMyBark () {
    // how do I have this function use the bark above and not Pug.bark?
    Dog.prototype.bark.call(this);
  }
}

没有很好的解决方案,可能是因为这通常可以避免。

【讨论】:

  • 在最后一个实例中,您可以使用super.bark.call(this) 而不是显式调用Dog
猜你喜欢
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 2020-03-02
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多