【问题标题】:TS - class method is undefined in callbackTS - 回调中未定义类方法
【发布时间】:2019-07-31 22:51:03
【问题描述】:

我认为代码值一千字。举个例子

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 类进行修改。

谢谢

【问题讨论】:

  • 在 javascript 中,this 取决于函数的调用方式,而不是定义的位置。由于您将this.sound 作为回调传递给另一个函数,因此当它被调用时,它将引用与您预期不同的this。你可能对这个问题感兴趣:How to access the correct this inside a callback?

标签: typescript class scope callback


【解决方案1】:

这是因为传递 this 时的 Javascript this 上下文。 传递 this 时,您应该始终将其绑定到当前上下文

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

箭头函数:

() => {}

箭头函数在词法上绑定它们的上下文,因此 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"
 }
}

【讨论】:

  • 这种方法只有在不继承Cat 时才是安全的。如果是,就会有a runtime error
【解决方案2】:

说明

在 JavaScript 中,this 是在调用函数时确定的。在您的情况下,sound(a) 使用 undefinedthis 上下文调用。

如果你坚持在sound(a)里面使用this,常见的解决办法有两种:

  • 使用类属性函数(箭头函数)代替方法
  • 在构造函数中绑定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"
    }
}

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多