javascript - 变量 "this"重新分配变量后上下文未更新

标签 javascript

我无法定义正确的术语以及我对以下代码的理解是否正确。

我创建了一个构造函数

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 实例。

如果我将 newGame 代码更改为:

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

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

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

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

当我在 newGame() 中调用 new BoardGame 时,“this”在重新分配后引用了旧对象,是什么保持了对旧对象的引用,这是一个闭包吗?范围?引用对象与值概念?

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

我相信正在发生的事情的基础与这个例子有关,尽管我没有 100% 清楚地掌握这个概念。

var a = {a: "A"};
var b = a;

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

所以在我的场景中,创建事件监听器时 this 的上下文是原始对象。然后,当在 newGame 函数中调用 new BoardGame 时,游戏引用会发生变化,但“this”引用仍然引用原始对象(不知道为什么它不会随之改变)。

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

最佳答案

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

当您调用game.newGame时:

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

所发生的只是一个新的 BoardGame 实例被分配给 game,而使用 bind 绑定(bind)到监听器的前一个实例尚未被分配已更改。

If I change my newGame code to this:

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

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

And run the newGame function, the "this" references, updates and changes the current object properties to the properties in the BoardGame constructor. It goes to the actual object instead of re-assigning.

是的,因为您将“实际对象”作为this传递,所以没有新对象。

I'm not sure why this makes such a big difference, shouldn't the context of this change to the new assigned object?

this 不是“上下文”,它是函数执行上下文的一个属性,由您调用函数的方式设置。

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

this 并不保存在闭包中,它是通过 bind (在这种情况下它是静态的)或通过函数的调用方式来设置的每次通话。它始终在当前函数的执行上下文中解析(ES6 箭头函数改变了这一点,但它们与此处无关)。

编辑

我认为你可以从对OP的编辑中得到它。

关于javascript - 变量 "this"重新分配变量后上下文未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27978302/

相关文章:

javascript - jQuery - 通过 event.target 属性获取元素的类

javascript - 卡在socket.io上

javascript - 为什么在这种情况下我需要 componentWillReceiveProps?

javascript - 传递一个向 $.when .done 发出 ajax 请求的函数

javascript - Uncaught TypeError : . unshift 不是函数

javascript - 用户单击图像几秒钟后如何重定向父页面?

javascript - jQuery 选择器重用最佳实践

javascript - 将 ondblclick 事件绑定(bind)到列表中的每个项目并在事件中传递该项目的值

javascript - 刷新 iframe 而不刷新整个页面

javascript - 如何从原型(prototype)中的url中提取参数?