Почему я получаю ошибку ссылки между моими классами JS?

#javascript

#javascript

Вопрос:

Я пытаюсь вызвать averageScore() функцию, объявленную в моем Player классе, из моего Leaderboard класса, но я получаю ошибку ссылки.

Удаление кода из моего Player класса в консоль работает нормально, но когда я пытаюсь вызвать его из Leaderboard , я получаю Reference error: add_score is undefined .

Вот мой класс player:

 class Player {

  constructor(player_id, score) {
   this.player_id = player_id;
   this.scores = [score];
   this.total = score;
   //this.average = this.total/this.scores.length;
    }

  addScore(score) {
    this.total  = score;
    this.scores.push(score);
    return score;
  }

  averageScore() {
    return this.scores.length ? this.total / this.scores.length : 0;
  }

  resetScore() {
    this.scores = [];
    this.score = 0;
    }

  };
  

И вот мой класс лидеров:

 class LeaderBoard extends Player {

  add_score = (player_id, score) => {
    if (!this.player_id) {
      var newPlayer = new Player(player_id, score);
      this.player_id = newPlayer;
    } else {
      var average = this.player_id.averageScore();
      return average.toFixed(1);
    }

  };
/*...(additional functions and closing bracket excluded)*/
  

Я ожидал, что averageScore будет отображаться при вызове add_score, но вместо этого я получаю ошибку ссылки — есть идеи?

Комментарии:

1. почему вы объявляете add_score как свойство класса в таблице лидеров?

2. У меня нет веской причины, почему, хотя я предполагаю, что в этом нет необходимости? Кроме того, могу ли я вложить класс Player в таблицу лидеров? Не уверен, какой наилучший подход

3. честно говоря, то, что вы закодировали, выглядит неправильно… почему таблица лидеров, предположительно список игроков, расширяет Player? и зачем вам устанавливать this.player_id … какой идентификатор в конструкторе Player должен быть экземпляром Player? Код имеет очень мало смысла

4. кроме того, единственная ошибка, которую я получаю с вашим кодом, — это this.player_id.averageScore если я создаю экземпляр LeaderBoard с аргументами типа new LeaderBoard(1,2), а затем пытаюсь add_score — никогда не получаю ошибку, которую вы получаете

5. нет, вам нужно создать экземпляр Player для доступа к функциям в конкретном объекте players

Ответ №1:

Для таблицы лидеров нет смысла расширять Player, поскольку таблица лидеров будет содержать список игроков

Рабочий пример см. в коде ниже

 class Player {
    constructor(player_id, score) {
        this.player_id = player_id;
        this.scores = [score];
        this.total = score;
        //this.average = this.total/this.scores.length;
    }

    addScore(score) {
        this.total  = score;
        this.scores.push(score);
        return score;
    }

    averageScore() {
        return this.scores.length ? this.total / this.scores.length : 0;
    }

    resetScore() {
        this.scores = [];
        this.score = 0;
    }

};
class LeaderBoard {
    constructor() {
        this.players = {};
    }
    addScore(player_id, score) {
        if (!this.players[player_id]) {
            this.players[player_id] = new Player(player_id, score);
        } else {
            this.players[player_id].addScore(score);
        }
        var average = this.players[player_id].averageScore();
        return average.toFixed(1);
    }
};
let x = new LeaderBoard();
console.log(x.addScore(1, 1)); // avg is 1 / 1 === 1
console.log(x.addScore(1, 3)); // avg is (1   3) / 2 === 2
console.log(x.addScore(1, 5)); // avg is (1   3   5) / 3 === 3
console.log(x.addScore(2, 7)); // avg for player 2 is 7 / 1 === 7  

Ответ №2:

Вы используете функцию со стрелкой вместо того, чтобы определять ее как обычно. Вот код, который следует использовать для LeaderBoard класса:

 class LeaderBoard extends Player {

  add_score(player_id, score) { //THIS LINE IS WHERE YOU WENT WRONG
    if (!this.player_id) {
      var newPlayer = new Player(player_id, score);
      this.player_id = newPlayer;
    } else {
      var average = this.player_id.averageScore();
      return average.toFixed(1);
    }

  };
/*...(additional functions and closing bracket excluded)*/
  

Комментарии:

1. версия функции со стрелкой работает так же, как и без стрелки в моем тестировании

2. В моем случае это работает только после того, как я меняю стрелку на не-стрелку

3. Я предполагаю, что OP использует babel с включенной предустановкой stage-3 — в противном случае ошибка была бы совершенно другой