传播复杂对象的语法
Spread syntax for complex objects
假设我有这样一个对象
let store = {
"articles": [{...}, {...}, ...],
"errors": { "p1": { "myNewObject":0 }, "p2": {...}, ...}
}
我想利用 Spread syntax 来 return 这个对象的克隆,其中 store.errors.p1
是一个新对象。以下是最简单的方法吗?
let newStore = { ...store, ...{ errors: { ...store.errors, p1: { "myNewObject":1 } } } }
您也可以使用 lodash.clonedeep,然后只需将 属性 更改为 store.errors.p1 = { "myNewObject": 1}
。
或者,如果您愿意,您可以创建一个函数 assocIn
(受 clojue 启发)以更惯用的方式执行此操作:
const assocIn = (obj, [key, ...rest], value) =>
({...obj, [key]: rest.length == 0 ? value : assocIn(obj[key], rest, value)});
store = assocIn(store, ['errors', 'p1'], { "myNewObject": 1})
如果您觉得这不可读,那么您可以使用 reduce
遍历 errors
对象并先更新对象,然后使用扩展语法。它可能会多一些代码行,但为了可读性会有所抵消。
const updatedkey = "p1";
const updatedData = {
"myNewObject": 1
};
const store = {
"articles": [{
...
}, {
...
}],
"errors": {
"p1": {
"myNewObject": 0
},
"p2": {
...
},
}
};
const updatedErrors = Object.keys(store.errors).reduce((acc, key) => {
const acc[key] = store.errors[key];
if (key === updatedkey) {
acc[key] = {
...acc[key],
...updatedData
}
}
return acc;
}, {});
const newStore = {
...store,
errors: updatedErrors
};
不,克隆您的商店并进行 p1
的深度复制并不是最简单的语法,但它非常接近:
let newStore = { ...store, ...{ errors: { ...store.errors, p1: { myNewObject: 1 } } } }
// ^^^^ ^
// |_______ not necessary ________________________________|
您可以删除 errors
周围的额外展开和括号。
const store = { articles: [{ a: 1 }], errors: { p1: { myNewObject: 0 }, p2: { a: 1 } } }
const newStore = { ...store, errors: { ...store.errors, p1: { myNewObject: 1 } } }
console.log(JSON.stringify(store))
console.log(JSON.stringify(newStore))
假设我有这样一个对象
let store = {
"articles": [{...}, {...}, ...],
"errors": { "p1": { "myNewObject":0 }, "p2": {...}, ...}
}
我想利用 Spread syntax 来 return 这个对象的克隆,其中 store.errors.p1
是一个新对象。以下是最简单的方法吗?
let newStore = { ...store, ...{ errors: { ...store.errors, p1: { "myNewObject":1 } } } }
您也可以使用 lodash.clonedeep,然后只需将 属性 更改为 store.errors.p1 = { "myNewObject": 1}
。
或者,如果您愿意,您可以创建一个函数 assocIn
(受 clojue 启发)以更惯用的方式执行此操作:
const assocIn = (obj, [key, ...rest], value) =>
({...obj, [key]: rest.length == 0 ? value : assocIn(obj[key], rest, value)});
store = assocIn(store, ['errors', 'p1'], { "myNewObject": 1})
如果您觉得这不可读,那么您可以使用 reduce
遍历 errors
对象并先更新对象,然后使用扩展语法。它可能会多一些代码行,但为了可读性会有所抵消。
const updatedkey = "p1";
const updatedData = {
"myNewObject": 1
};
const store = {
"articles": [{
...
}, {
...
}],
"errors": {
"p1": {
"myNewObject": 0
},
"p2": {
...
},
}
};
const updatedErrors = Object.keys(store.errors).reduce((acc, key) => {
const acc[key] = store.errors[key];
if (key === updatedkey) {
acc[key] = {
...acc[key],
...updatedData
}
}
return acc;
}, {});
const newStore = {
...store,
errors: updatedErrors
};
不,克隆您的商店并进行 p1
的深度复制并不是最简单的语法,但它非常接近:
let newStore = { ...store, ...{ errors: { ...store.errors, p1: { myNewObject: 1 } } } }
// ^^^^ ^
// |_______ not necessary ________________________________|
您可以删除 errors
周围的额外展开和括号。
const store = { articles: [{ a: 1 }], errors: { p1: { myNewObject: 0 }, p2: { a: 1 } } }
const newStore = { ...store, errors: { ...store.errors, p1: { myNewObject: 1 } } }
console.log(JSON.stringify(store))
console.log(JSON.stringify(newStore))