TS - 类方法在回调中是未定义的

问题描述 投票:1回答:2

我认为代码值得千言万语。举个例子

class Cat {

 constructor() {
  this.meow("roar", this.sound)
 }

 meow(a, callback) {
  callback(a)
 }

 sound(a) {
  console.log(a)
  console.log(this.sayMeow) <----- THIS IS UNDEFINED
 }

 sayMeow() {
  return "Meow"
 }
}

如你所见,方法sayMeow()未定义。你能解释一下为什么以及如何解决它?

这只是我需要使用回调的更复杂代码的简化表示。我需要知道为什么在回调函数中未定义方法。请不要写这个简单的Cat类的修改。

谢谢

typescript class scope callback
2个回答
3
投票

说明

在JavaScript中,this是在调用函数时确定的。在你的情况下,sound(a)被称为thisundefined背景。

如果你坚持在this中使用sound(a),有两种常见的解决方案:

  • 使用类属性函数(箭头函数)而不是方法
  • 绑定构造函数中的this上下文

第一种方法是由React推广的,它工作得很好,因为用户创建的React组件是最终的类。但是,如果您正在进行面向对象编程并且希望继承Cat类,则不能将此方法用于it breaks inheritance

在构造函数中将执行上下文绑定到类的实例。

class Cat {
    constructor() {
        this.sound = this.sound.bind(this)
        this.meow("roar", this.sound)
    }

    meow(a, callback) {
        callback(a)
    }

    sound(a) {
        console.log(a)
        console.log(this.sayMeow)
    }

    sayMeow() {
        return "Meow"
    }
}

1
投票

这是因为Javascript这个上下文传递时。传递此信息时,应始终将其绑定到当前上下文

this关键字根据调用它的上下文绑定到不同的值。但是,对于箭头函数,这是词法绑定。这意味着它从包含箭头函数的代码中使用它。

箭头功能:

() => {}

箭头函数在词法上绑定它们的上下文,因此这实际上是指原始上下文。

class Cat {

 constructor() {
  this.meow("roar", this.sound)
 }

 meow(a, callback) {
  callback(a)
 }

 sound = (a) => {
  console.log(a)
  console.log(this.sayMeow)
 }

 sayMeow() {
  return "Meow"
 }
}
© www.soinside.com 2019 - 2024. All rights reserved.