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

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

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

Вот мой класс игрока:

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 вызывает его, но вместо этого я получаю справочную ошибку - есть идеи?

почему вы объявляете add_score свойством класса в LeaderBoard?

Jaromanda X 10.04.2019 03:17

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

James 10.04.2019 03:22

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

Jaromanda X 10.04.2019 03:24

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

Jaromanda X 10.04.2019 03:26

Я думал, что мне понадобится extends Player, чтобы иметь доступ к функциям в Player

James 10.04.2019 03:26

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

Jaromanda X 10.04.2019 03:27

и об этом позаботились var newPlayer = new Player... верно?

James 10.04.2019 03:27

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

Jaromanda X 10.04.2019 03:34

хммм... интересно... addScore в Player и add_score в LeaderBoard... вы показали куда/как вы звоните add_score - может вместо этого должно быть addScore?

Jaromanda X 10.04.2019 03:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
9
179
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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)*/

версия со стрелкой работает так же, как и без стрелки в моем тестировании

Jaromanda X 10.04.2019 03:26

В моем это работает только после того, как я изменю стрелку на нестрелку

VFDan 10.04.2019 03:35

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

Jaromanda X 10.04.2019 03:37
Ответ принят как подходящий

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

См. код ниже для рабочего примера

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.info(x.addScore(1, 1)); // avg is 1 / 1 === 1
console.info(x.addScore(1, 3)); // avg is (1 + 3) / 2 === 2
console.info(x.addScore(1, 5)); // avg is (1 + 3 + 5) / 3 === 3
console.info(x.addScore(2, 7)); // avg for player 2 is 7 / 1 === 7

Другие вопросы по теме