在JavaScript

问题描述:

返回一个新的对象,具有一些额外的属性我有一个对象在JavaScript

usersById: { 
    1: { name: 'John' }, 
    2: { name: 'Michelle' }, 
    ... 
} 

我想在ID = 2的新属性age返回相同的对象,但第一填充物,但坚持不变性。

我想这会是这样的

return { 
    ...usersById, 
    ...usersById[2].age = 40 
} 

,但我收到一条错误In this environment the sources for assign MUST be an object. This error is a performance optimization and not spec compliant

另外,我想这应该是这样的

return Object.keys(usersById).map(userId => { 
    if (userId === 2) { 
    return { 
     ...usersById[2], 
     ...age = 40 
    } 
    } 
    return usersById[userId] 
}) 

但它返回一个数组,而不是一个对象。

+1

地图总是返回一个数组,因为它是一个数组方法。 – evolutionxbox

+0

我知道,但不是'reduce'还可以返回一个对象与'arr.reduce((accumulator,item)=> {...},{})''? – Jamgreen

+0

这不是重言式。数组方法并不总是返回一个数组。我不应该用这个解释。 – evolutionxbox

你有正确的想法,但语法错误。试试这个:

return { 
    ...usersById, 
    2: { 
    ...usersById[2], 
    age: 40 
    } 
} 

或者,如果关键是动态的,你可以这样做:

let key = 2; 
return { 
    ...usersById, 
    [key]: { 
    ...usersById[key], 
    age: 40 
    } 
} 
+0

它的工作原理!谢谢:D – Jamgreen

+1

@Jamgreen很高兴我可以帮助:) –

+0

我很抱歉坚持到这里,但为什么不试试usersById [2] .age = 40;返回usersById; ?在这个答案中的解决方案返回数组与原始对象作为第一个元素,并更新子对象作为第二个元素。我很抱歉,但我不明白这里的东西,并希望如果你更广泛地解释它......谢谢! – GSazheniuk

你可以使自己的函数来填充值返回相同的对象

简单的例子:

var usersById = { 
 
    1: { name: 'John' }, 
 
    2: { name: 'Michelle' }, 
 
} 
 

 
usersById = oneLevelDeepAssign(usersById,2,{age:21}) 
 

 

 
function oneLevelDeepAssign(object, key, objectToAssign){ 
 

 
    return Object.assign({},object,{[key]:Object.assign({},object[key],objectToAssign)}) 
 

 
} 
 

 
console.log(usersById);