【问题标题】: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 类进行修改。
谢谢
【问题讨论】:
标签:
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"
}
}
【解决方案2】:
说明
在 JavaScript 中,this 是在调用函数时确定的。在您的情况下,sound(a) 使用 undefined 的 this 上下文调用。
如果你坚持在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"
}
}