作用域变量正在创建引用而不是新实例

Scoped variable is creating a reference instead of new instance

本文关键字:新实例 实例 变量 创建 引用 作用域      更新时间:2023-09-26

遇到一个奇怪的Javascript错误,很高兴能得到一些见解。我已经设法调试它以了解问题是什么,我只是无法弄清楚原因以及解决它的非黑客方法。

正在尝试创建一个数组的新实例作为函数中的变量,这样我就可以在不影响主数组的情况下操作它。相反,我得到了某种引用,因此对我的新变量进行操作也会影响ids等于的数组ids

我简化了我的代码以更清楚地演示问题:

var defence = {
    selectedIDs: new Array(),
    toggleTerm: function(term, id) {
        // add to the main array
        this.selectedIDs.push(5);
        // adds to this.selectedIDs
        this.showTweet();
    },
    showTweet: function() {
        // copy the array as a new variable in the scope of the function
        var ids = this.selectedIDs;
        if (ids.length == 1) {
            ids.push(10); // this pushes to 'ids' AND 'this.selectedIDs'
        }
        console.log(this.selectedIDs); // outputs [5, 10]
    }
}

同样在JSFiddle中

我一直认为var ids = this.selectedIDs会有效地将this.selectedIDs的内容复制到该新实例中 - 但事实似乎并非如此。

关于为什么会发生这种情况的任何想法,以及解决它的最佳方法(除了通过 for 循环之类的东西手动重新创建它)?

我一直认为var ids = this.selectedIDs会 有效复制内容

好吧,但你的理解是错误的。 这是一项任务。

相反,请考虑以下情况:

var ids = this.selectedIDs.slice()

我一直认为var ids = this.selectedIDs会 有效地 this 的内容。selectedID 复制到新的 实例 - 但情况似乎并非如此。

我不知道如何描述这一点,除了"不,这根本不会发生"。JavaScript 并不C++;当您为变量分配某些内容时,永远不会复制它。你总是得到一个引用,除了基元的情况,它是不可变的,这使得这一点变得毫无意义。(呵呵。

您可以使用concat,但如果这不是实际情况,可能会有更合适的东西。

showTweet: function() {
    var ids = this.selectedIDs;
    if (ids.length === 1) {
        ids = ids.concat(10); // Array.prototype.concat returns a new array
    }
    console.log(this.selectedIDs); // outputs [5]
}