Javascript : 修改对象并将新索引添加到 属性

Javascript : Modify object and add new index to a property

我的对象是这样的:

let items = 
    [
        {
            "creationTimeStamp": "2022-05-31T17:04:28.000Z",
            "modifiedTimeStamp": "2022-05-31T17:04:28.000Z",
            "locations": [
                {
                    "id": "5ao",
                    "name": "Store1"
                }
            ],
            "typeId": "Lead"
        }
    ]

我正在尝试将以下对象推入 locations 属性:

{
    "id": "9a0",
    "name": "Store2"
}

我试过

items1 = [];
for (var i = 0; i < items.length; i++) {
    items1.id = "9a0";
    items1.name = "Store2";
    //9 is some static index value added
    Object.assign({9 : items1}, items[i].locations);
}

如果我 console(Object.assign({9 : items1}, items[i].locations)); 我可以看到里面有 2 个数组,但是我的项目 locations 属性 仍然是一样的。

我的期望如下:

[
    {
        "creationTimeStamp": "2022-05-31T17:04:28.000Z",
        "modifiedTimeStamp": "2022-05-31T17:04:28.000Z",
        "locations": [
            {
                "id": "5ao",
                "name": "Store1"
            },
            {
                "id": "9a0",
                "name": "Store2"
            }
        ],
        "typeId": "Lead"
    }
]

我也尝试使用 items[i].locations.push(item1) 但后来得到:

TypeError: Cannot add property 9, object is not extensible

我也试过给items[i].locations分配一个新的数组,但后来得到:

TypeError: Cannot assign to read only property 'locations' of object '#'

我该怎么做才能得到想要的结果?

您似乎期望 Object.assign 的第二个参数会发生变化。但这是第一个参数发生了变化。这意味着您的 .locations 而不是 变异的。此外,在评论中您指出 locations 无法扩展并且 属性 是 read-only.

这意味着您需要一个全新的对象。

一些其他备注:

  • 不要将 items1 初始化为数组,因为它应该是一个普通对象。

  • 使用 constletvar 声明变量并避免隐式全局声明。

  • 在循环内声明 items1 对象更安全,因此您每次都创建一个新对象并且不会改变 same 目的。对于您的示例代码,这没有什么区别,但它可能会导致意外行为。

  • 因为除了 items[i] 之外,您不需要 i,而您实际上需要一个全新的结构,所以请使用 .map

所以:

items = items.map(item => {
    let obj = {
        id: "9a0",
        name: "Store2"
    };
    return {...item, locations: item.locations.concat(obj) };
});

items 是一个数组,因此它必须访问数组的第一个位置,这将是建议的对象。 有了这个,您将从建议的对象中提取 location 属性,因为这是一个数组,您可以使用 push 函数插入新对象

items[0]
// ->
// {
//   creationTimeStamp: '2022-05-31T17:04:28.000Z',
//   modifiedTimeStamp: '2022-05-31T17:04:28.000Z',
//   locations: [ { id: '5ao', name: 'Store1' } ],
//   typeId: 'Lead'
// }

我试试这个:

items[0].locations.push({"id": "9a0", "name": "Store2" })

现在:

items[0]
//->
// {
//   creationTimeStamp: '2022-05-31T17:04:28.000Z',
//   modifiedTimeStamp: '2022-05-31T17:04:28.000Z',
//   locations: [ { id: '5ao', name: 'Store1' }, { id: '9a0', name: 'Store2' }],
//   typeId: 'Lead'
// }

我总是从功能和 immutability-by-default 的角度思考,所以我的方法可能看起来像这样,addLocationToAll 构建在更简单的 addLocation 之上。代码相当简单:

const addLocation = (newLoc) => ({locations, ...rest}) => 
  ({...rest, locations: locations .concat (newLoc)})

const addLocationToAll = (newLoc) => (items) => 
  items .map (addLocation (newLoc))

const items = [{creationTimeStamp: "2022-05-31T17:04:28.000Z", modifiedTimeStamp: "2022-05-31T17:04:28.000Z", locations: [{id: "5ao", name: "Store1"}], typeId:"Lead"}]
const newLoc = {id: "9a0", name: "Store2"}

console .log (addLocationToAll (newLoc) (items))
.as-console-wrapper {max-height: 100% !important; top: 0}