#javascript #spread-syntax #ecmascript-2018
#javascript #расширенный синтаксис #ecmascript-2018
Вопрос:
Предположим, у меня есть объект, подобный этому
let store = {
"articles": [{...}, {...}, ...],
"errors": { "p1": { "myNewObject":0 }, "p2": {...}, ...}
}
Я хочу воспользоваться синтаксисом распространения, чтобы вернуть клон этого объекта, где store.errors.p1
является новым объектом. Является ли следующий самый простой способ?
let newStore = { ...store, ...{ errors: { ...store.errors, p1: { "myNewObject":1 } } } }
Комментарии:
1. Да, это так. —
2. @x539, нет, это не так, распространение и скобки вокруг
errors
могут быть удалены3. @jo_va ваше право, должно быть, наблюдал за этим
Ответ №1:
Нет, это не самый простой синтаксис для клонирования вашего хранилища и глубокой копии 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))
Ответ №2:
Вы также можете использовать что-то вроде 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})
Ответ №3:
Если вы чувствуете, что это не читается, вы можете использовать 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
};