更改 javascript 中嵌套键值的值

Change value of a nested key value in javascript

我试图更改嵌套键值结构中的特定值,但当我设置一个值时,它会更改所有键的值。

初始数据为:

   const data = {
      "1.157685561": {
        "1222344": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [0, 0],
            [0, 0],
            [0, 0]
          ]
        },
        "1222345": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [0, 0],
            [0, 0],
            [0, 0]
          ]
        }
      }
    }

我想更改特定路径的值

    data['1.157685561']['1222344']['batl'][0] = [1,2]

但是结果是错误的。因为它改变了:

最终结果:

    {
      "1.157685561": {
        "1222344": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [1, 2],
            [0, 0],
            [0, 0]
          ]
        },
        "1222345": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [1, 2],
            [0, 0],
            [0, 0]
          ]
        }
      }
    }

源代码:https://playcode.io/301552?tabs=console&script.js&output

检查provided code的这一部分:

function createEmptyMarketData(runners) {
    const data = {};
    const marketData = {
        batb: [
          [0, 0],
          [0, 0],
          [0, 0]
        ],
        batl: [
          [0, 0],
          [0, 0],
          [0, 0]
        ]
    };

    for (const runner of runners) {
        data[runner] = marketData;
    }

    return data;
}

使用 for (const runner of runners) {data[runner] = marketData;} 您将存储对同一对象的多个引用。这是个问题。

一个可能的解决方案是将 marketData 更改为每次调用都会生成新 object 的方法。示例:

function createEmptyMarketData(runners)
{
    const data = {};

    const marketData = () => ({
        batb: [[0, 0], [0, 0], [0, 0]],
        batl: [[0, 0], [0, 0], [0, 0]]
    });

    for (const runner of runners)
    {
        data[runner] = marketData();
    }

    return data;
}

新版本: https://playcode.io/301583?tabs=console&script.js&output

是的,@Shidersz 是对的。我还检查了,因为当我从 Node 终端尝试时,我看不到任何问题,因为您在问题中粘贴的对象是由函数创建的对象(所以它工作正常)。

> const data = {
...       "1.157685561": {
.....         "1222344": {
.......           "batb": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ],
.......           "batl": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ]
.......         },
.....         "1222345": {
.......           "batb": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ],
.......           "batl": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ]
.......         }
.....       }
...     }
undefined
> 
> data['1.157685561']['1222344']['batl'][0] = [1,2]
[ 1, 2 ]
> 
> data
{ '1.157685561':
   { '1222344': { batb: [Array], batl: [Array] },
     '1222345': { batb: [Array], batl: [Array] } } }
> 
> data['1.157685561']['1222344']['batl'][0]
[ 1, 2 ]
> 
> data['1.157685561']['1222345']['batl'][0]
[ 0, 0 ]
> 

我心想,这到底是怎么回事。最后,我检查了您正在创建 data 的代码。您在此处为不同的键引用相同的对象。

因此,更新单个对象就像影响其他对象,但在内部它们只是对存储真实对象的相同内存位置的引用。

This What is the most efficient way to deep clone an object in JavaScript? would be really very very helpful for you to understand the concept of Deep & Shallow copy of variables.

您终于可以在 https://playcode.io/301586?tabs=console&script.js&output 查看更新后的代码了。我刚刚复制了外部 marketData 并放置在 for 循环中。

就是这样。非常感谢你。