我正在阅读Redux减速器(https://redux.js.org/introduction/three-principles)的介绍,其中包含以下减速器示例:
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
text: action.text,
completed: false
}
]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
从其文档(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)看来,Object.assign()
将“合并”传递给它的所有对象。但是,在这种情况下,todo
和{completed: true}
已经是对象,因此我看不到将空对象文字{}
作为{{1的第一个参数}}。有人可以澄清吗?
答案 0 :(得分:3)
使用Object.assign
时,您给它的第一个对象将把所有其余对象合并到其中。也就是说,第一个对象将被突变。
如果要避免使要合并的对象发生变异,则将空对象作为第一个参数传入会有所帮助,以防止任何组件对象发生更改。
下面是一个展示差异的示例:
const obj1 = {
foo: "bar"
}
const obj2 = {
key: "value"
}
// Here, obj1 is the same after the Object.assign call
console.log(Object.assign({}, obj1, obj2));
console.log(obj1)
console.log(obj2)
console.log("\n\n")
// Note that after this call, obj1 holds both keys. So this will mutate it:
console.log(Object.assign(obj1, obj2));
console.log(obj1) // This is different now
console.log(obj2)
答案 1 :(得分:1)
如果您不传入空对象,则原始todo
对象将被修改。这可能是您想要的,但通常不是。
这是由于对象都是引用的方式,默认情况下不会克隆。
答案 2 :(得分:1)
简短答案:对象和数组是通过引用分配的。
在此示例中,更改一个将更改另一个,但它们并非一成不变的:
let x = {param:1}
const foo = (a) => {
a.param +=1;
console.log('response', x, a)
}
foo(x);
要解决此问题,我们使用Object.assign()
let x = {param:1}
const foo = (a) => {
let b = Object.assign({}, a);
b.param +=1;
console.log('response', b, x)
}
foo(x);