变量“this”上下文在重新赋值变量后未更新

Variables "this" context not updating after re-assigning variable

本文关键字:变量 赋值 更新 新赋值 this 上下文      更新时间:2023-09-26

我在定义正确的术语时遇到问题,如果我对以下代码的理解是正确的。

我创建了一个构造函数

function BoardGame () {
    this.count = 10;
    this.random = Math.floor((Math.random() * 100) + 1);
}
BoardGame.prototype.getNumber = function(){
    // this is a button that is clicked
    $('.inputField').on('click', function (event) {
        this.guess= parseInt($('#inputField').val(), 10);
        $("'#inputField'").val("");
          this.validChecker();
      }.bind(this));
}
BoardGame.prototype.validChecker = function() {
    if (this.guess < 1 || this.guess > 100) {
    $('#warning').append($('<p></p>'));
  }
};
BoardGame.prototype.newGame = function () {
    game = new BoardGame();
}
$(document).ready(function(){
    game = new BoardGame();
    game.getNumber();
});

在 document.ready 函数中,将创建一个 BoardGame 的新实例,并将引用设置为全局范围内的 game 变量。

然后,创建事件侦听器。

当单击 getNumber 中的事件侦听器时,它会传递"this"上下文(游戏),并将其用作 this 引用。 它调用this.validChecker() .

在某些时候,将调用game.newGame()。现在,一个新的 boardGame 实例被重新分配给游戏变量。 如果我查看我的"this"引用,它引用旧的 BoardGame 对象(在重新分配之前),而不是最近创建的新 BoardGame 实例。

如果我将我的新游戏代码更改为:

BoardGame.prototype.newGame = function () {
    BoardGame.call(this);
}

并运行newGame函数,"this"引用,更新和更改当前对象属性到BoardGame构造函数中的属性。 它转到实际对象而不是重新分配。 我不确定为什么这会产生如此大的差异,这种更改的上下文不应该更改为新分配的对象吗?

当我在 newGame 函数中调用新的 BoardGame() 时,为什么"this"引用没有更改为新对象?

更改

当前对象与重新分配新对象之间似乎存在差异,即使我可以更改对象的属性。这是怎么回事?

当我在 newGame() 中调用新的 BoardGame 并且"this"在重新分配后引用旧对象时,是什么保留了对旧对象的引用,这是一个闭包吗?引用对象与值概念?

编辑:我想补充一点,当我使用"new BoardGame()""重置"游戏变量,然后单击按钮时,"this"引用旧对象。但是,如果我在自己的行上调用game.getNumber();,"this"会引用新的游戏对象,这就是我所期望的。

我相信正在发生的事情的基础与这个例子有关,即使我对这个概念没有 100% 的清晰掌握。

var a = {a: "A"};
var b = a;
a = "hello"
b; // still references {a: "A"}

因此,在我的方案中,创建事件侦听器时的上下文是原始对象。 然后,当在newGame函数中调用new BoardGame时,游戏引用会发生变化,但"this"引用仍在引用原始对象(不确定为什么它不会随之改变)。

当我们使用 BoardGame.call(this) 时,无论我们在哪里看,这都只指所有代码中的一个对象。 我们永远不会创建第二个对象。

我不确定我是否完全理解您的困惑,希望以下内容有所帮助。

当您调用 game.newGame 时:

BoardGame.prototype.newGame = function () {
    game = new Game();
}

发生的情况只是将一个新的 BoardGame 实例分配给游戏,使用 bind 绑定到侦听器的先前实例尚未更改。

如果我将我的新游戏代码更改为:

BoardGame.prototype.newGame = function () { 棋盘游戏(这个); }

这将构造函数

作为函数调用,并将旧游戏对象传递给构造函数。它只是更新传递给它的游戏对象的属性,而不会创建一个新的对象。

并运行newGame函数,"this"引用,更新和 将当前对象属性更改为 棋盘游戏构造函数。它转到实际对象而不是 重新分配。

是的,因为您按传递了"实际对象",所以没有新对象。

我不确定为什么这会产生如此大的差异,这种更改的上下文不应该更改为新分配的对象吗?

这不是"上下文",它是函数执行上下文的属性,由调用函数的方式设置。

这有很大的不同,因为没有新对象,因为 BoardGame 不是用 new 调用的,所以你把它作为一个函数来调用,而不是一个构造函数。

这不是在闭包中保存的,它由 bind 设置(在这种情况下它是静态的)或每次调用时调用函数的方式设置。它始终在当前函数的执行上下文中解析(ES6 箭头函数会改变这一点,但它们在这里无关紧要)。

编辑

我想你从对 OP 的编辑中得到了它。

这部分代码应该在新游戏函数中

new Game();

改为这样阅读:

new BoardGame();

编辑:没关系。我看到您在我键入时进行了更改。