【问题标题】:Access an instance from a function outside of the object constructor从对象构造函数之外的函数访问实例
【发布时间】:2019-07-16 08:00:33
【问题描述】:

我有一个问题,经过多次尝试解决后无法理解。

为了帮助您理解,这里有 2 个类(游戏和棋盘),以及带有 jQ​​uery 按键控件的第三个文件。游戏关乎游戏逻辑,板关展示。

这是我希望足以理解的部分代码。

// GAME CLASS
function Game(width, height) {
  this.width = width;
  this.height = height;

  this.forbiddenPosition = [];

  this.chartBoard = this.resetBoard();

  this.generateGame();
}

Game.prototype.generateGame = function () {
  this.player1 = new Player("Joueur 1", 100, dagger);
  this.player2 = new Player("Joueur 2", 100, dagger);
  const playerArray = [this.player1, this.player2];
}

Game.prototype.getPlayer1 = function () {
  return this.player1;
};

Game.prototype.getPlayer2 = function () {
  return this.player2;
};
Game.prototype.switchTurn = function (player1, player2) {

  console.log(player1);
  console.log(player2);
};

// BOARD CLASS
const ctx = $('#board').get(0).getContext('2d');

function Board (width, height) {
  this.width = width;
  this.height = height;
  this.game = new Game(this.width, this.height);

  this.displayInfoPlayers(this.game.getPlayer1(), this.game.getPlayer2());
}


Board.prototype.displayInfoPlayers = function (player1, player2) {
  $('.canvas-side__left').css('visibility', 'visible');
  $('.canvas-side__right').css('visibility', 'visible');
  $('.canvas-side__left').addClass('animated slideInLeft');
  $('.canvas-side__right').addClass('animated slideInRight');

  $(".canvas-side__left").html("<h2 class='canvas-side--title'>" + player1.name + "</h2><p class='canvas-side--health'>" + player1.health + "</p><p class='canvas-side--health'>" + player1.weapon.name + "</p>");

  $(".canvas-side__right").html("<h2 class='canvas-side--title'>" + player2.name + "</h2><p class='canvas-side--health'>" + player2.health + "</p><p class='canvas-side--health'>" + player2.weapon.name + "</p>");
};

// CONTROL
$(document).on('keypress', function (e) {
  if (e.which == 13) {
    Game.prototype.switchTurn(Game.prototype.getPlayer1(), Game.prototype.getPlayer2());
    e.stopPropagation();
  }
});

Board 类链接到 Game 类,因此使用它。使用 jQuery 代码的控件在第三个文件中,而不是在一个类中。

当我按 Enter 键时,player1 和 2 未定义。我尝试了不同的方法来调用 getter 函数,但没有任何效果。我还尝试将控件放入游戏文件中,但仍然没有。

我得到 undefined 或 getPlayer1() 不是函数。

我正在寻找一种从任何地方调用这些 getter 函数的方法,以便我可以使用我需要在板上移动的 player1 和 2。

【问题讨论】:

  • Game.prototype.getPlayer1() 将返回undefined,因为this 指的是Game.prototype 而不是Game 的实例。您需要使用const game = new Game() 等新运算符创建Game 的实例,然后运行game.getPlayer1()
  • @adiga 但是函数返回this.player1。这就是为什么我不明白这个问题。
  • 正如我在上一条评论中提到的,当您调用Game.prototype.getPlayer1() 时,this 指的是Game.prototypeGame.prototype 内部没有 player1 属性。它只存在于使用new operator 创建的Game 对象上。应该是:const game = new Game(); game.getPlayer1()
  • @adiga 谢谢。

标签: javascript jquery oop object


【解决方案1】:

那里有几个问题。

  1. 按键事件处理程序使用Game.prototype,而不是Game 的实例。您想使用您在某处创建并存储的Game 实例。 Game.prototype 没有 player1player2 属性。它们被Game 构造函数添加到Game 的实例中。从来没有将它们添加到 Game.prototype(这是正确的,它们不应该出现在原型上)。

  2. 不需要getPlayer1等,可以直接访问player1player2。 (可能player1player2 设为私有并仅为它们提供访问器,但目前有点复杂,可能还不是你想要的。)

  3. Game方法中,你需要始终如一地使用this.player1this.player2,不要传球。

  4. Board 创建Game 的实例似乎很奇怪。看来应该是反过来了。

我建议从这项任务中退后一步,先尝试一些更简单的事情(比如创建一个类、一个类的实例,并在事件处理程序中使用该实例),然后逐步增加复杂性并确保在每个阶段你都清楚发生了什么。随着您的进行,您可能有更具体的问题,您可以在 SO 上发布(经过深入研究等)。

【讨论】:

  • 谢谢。那么如果我不将 player1 和 player2 设为私有,那么 getPlayer1 现在就没有用了吗?我尝试以实用的方式工作,但我仍在学习。我创建了一个 Game in Board 的实例,因为显示器正在等待 Game 的变化(游戏的逻辑),并且只显示它。
  • @GrégoryHuyghe - 对,就你现在所拥有的而言,player1getPlayer1 具有相同的可见性,所以......(我应该注意,如果你正在尝试在函数式编程方式,你可能根本不会使用构造函数和new。)
  • 我应该使用什么来代替构造函数和 new 运算符?函数式编程中没有类?
  • @GrégoryHuyghe - 我建议使用 FP 入门或教程。所以 cmets 不是写一个的地方,无论如何我都没有资格这样做。 :-)(我对 FP 的了解很少。)我的印象是,不,在编写 FP JavaScript 时,您不会使用 JavaScript 的 constructor-function-and-new 模式;相反,我认为你直接构建对象。
【解决方案2】:

你可以做这样的事情,它应该可以工作。本质上,您将尝试访问的函数原型化,直到构造函数之后才声明。

class Test {
  constructor() {
    this.five = Test.prototype.getFive();
  }

  getFive() {
    return 5;
  }
}

let test = new Test();
console.log(test.five); // Returns 5

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2016-06-19
    • 2014-11-28
    相关资源
    最近更新 更多