TS - метод класса не определен в обратном вызове - PullRequest
1 голос
/ 10 марта 2019

Я думаю, что код стоит тысячи слов. Возьмите этот пример

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.

Спасибо

Ответы [ 2 ]

3 голосов
/ 10 марта 2019

Объяснение

В JavaScript this определяется при вызове функции. В вашем случае sound(a) вызывается с контекстом this undefined.

если вы настаиваете на использовании this внутри sound(a), есть два общих решения:

  • использовать метод свойства класса ( функция стрелки ) вместо метода
  • связывает контекст this в конструкторе

Первый подход был популяризирован React, и он работал нормально, потому что созданные пользователем компоненты React должны быть конечными классами. Однако, если вы занимаетесь объектно-ориентированным программированием и ожидаете, что ваш класс Cat будет унаследован, вы не сможете использовать этот подход для , поскольку он нарушает наследование .

Решение

Свяжите контекст выполнения с экземпляром вашего класса в конструкторе.

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 голос
/ 10 марта 2019

Это из-за Javascript этого контекста при передаче 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"
 }
}
...