首页 > 解决方案 > Push 覆盖对象内部数组的内容,但不覆盖外部数据

问题描述

我有一个循环通过数据库响应并将其转换为 Json 数据的代码,但是当我尝试将结果元素添加到数组中时,数组中的所有先前元素都被最后一个输入的元素覆盖,即数据被覆盖的只是对象内部的数组,而不是外部数据。

例如:(参见costoventa值)

我必须得到

[
    {
    "masaTipo_id": 3,
    "masaTipo_nombre": "Panqueque",
    "diet": 1,
    "cuadrada": 1,
    "precioTamano": [
        {
            "tamano_id": 1,
            "tamano": "1/2",
            "tamano_personas": "6 personas",
            "costo": 20,
            "venta": 20
        } (...)
    ]
    },
    {
    "masaTipo_id": 2,
    "masaTipo_nombre": "Hoja",
    "diet": 0,
    "cuadrada": 0,
    "precioTamano": [
        {
            "tamano_id": 1,
            "tamano": "1/2",
            "tamano_personas": "6 personas",
            "costo": 10,
            "venta": 10
        } (...)
    ]
    }

但相反我得到了

[
    {
        "masaTipo_id": 3,
        "masaTipo_nombre": "Panqueque",
        "diet": 1,
        "cuadrada": 1,
        "precioTamano": [
            {
                "tamano_id": 1,
                "tamano": "1/2",
                "tamano_personas": "6 personas",
                "costo": 10,
                "venta": 10
            } (...)
    },
    {
        "masaTipo_id": 2,
        "masaTipo_nombre": "Hoja",
        "diet": 0,
        "cuadrada": 0,
        "precioTamano": [
            {
                "tamano_id": 1,
                "tamano": "1/2",
                "tamano_personas": "6 personas",
                "costo": 10,
                "venta": 10
            } (...)
        ]
},

代码是:

schemas = [];
schema  = require('./schemas/torta');
for(let i = 0; i < rows.length; i+=4){
    schema.masaTipo_id               = rows[i].masaTipo_id;
    schema.masaTipo_nombre           = rows[i].masaTipo_nombre;
    schema.diet                      = rows[i].diet;
    schema.cuadrada                  = rows[i].cuadrada;
    schema.sucursal_id               = rows[i].sucursal_id;
    schema.sucursal_rut              = rows[i].sucursal_rut;
    schema.sucursal_nombre           = rows[i].sucursal_nombre;
    schema.sucursal_direccion        = rows[i].sucursal_direccion;
    schema.sucursal_giro             = rows[i].sucursal_giro;
    schema.sucursal_contactoNombre   = rows[i].sucursal_contactoNombre;
    schema.sucursal_contactoEamail   = rows[i].sucursal_contactoNombre;
    for(let j = 0; j < 4; j++){
        schema.precioTamano[j].tamano_id       = rows[i+j].tamano_id;
        schema.precioTamano[j].tamano          = rows[i+j].tamano;
        schema.precioTamano[j].tamano_personas = rows[i+j].tamano_personas;
        schema.precioTamano[j].costo           = rows[i+j].costo;
        schema.precioTamano[j].venta           = rows[i+j].venta;
    }
    schemas.push(Object.assign({}, schema));
    schema = require('./schemas/torta');
}

我已经尝试过这里提供的其他相关解决方案,但没有成功,并且在其他任何地方都没有看到这种特殊情况(只有对象内部的数组被覆盖)。我希望你能帮帮我!问候!

标签: javascriptarraysjsondatabase

解决方案


您的代码中有两个陷阱,它们共同导致您看到的结果:

  1. Object.assign()不会进行深度克隆,而只会进行浅拷贝。因此,对于复杂类型的属性(如您的schema.precioTamano数组),仅复制一个引用,即两个对象都指向相同的(在标识中而不是在相等中)数组。

  2. require有一个内部缓存,其中所需的“事物”通过键存储。当多次需要相同的键时,返回相同的“事物”。在您的情况下,我假设require('./schema/torta')返回一个 JSON 对象。当多次需要这个对象时,你总是会得到相同的(在身份中,而不是在平等中)对象

将 1 和 2 放在一起,schemas数组中的所有元素的precioTamano属性都指向同一个数组。因此,它们当然都包含相同的值(在您的情况下,是您从数据库中读取的最后一行的值),如果您更改其中一个,您将更改所有这些值。

针对您的情况的一个简单解决方法(因为它可能只处理 JSON 对象)可以使用JSON.parseJSON.stringify不是Object.assign

schemas.push(JSON.parse(JSON.stringify(schema));

因为这将创建您的架构对象的真正深层克隆。


推荐阅读