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
初始化为数组,因为它应该是一个普通对象。
使用 const
、let
或 var
声明变量并避免隐式全局声明。
在循环内声明 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}
我的对象是这样的:
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
初始化为数组,因为它应该是一个普通对象。使用
const
、let
或var
声明变量并避免隐式全局声明。在循环内声明
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}