Estou tentando criar um método de mapa de cópia profunda para meu projeto Redux que funcionará com objetos em vez de matrizes. Eu li que no Redux cada estado não deve mudar nada nos estados anteriores.
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
output[key] = callback.call(this, {...object[key]});
return output;
}, {});
}
Funciona:
return mapCopy(state, e => {
if (e.id === action.id) {
e.title = 'new item';
}
return e;
})
No entanto, ele não copia profundamente os itens internos, então preciso ajustá-lo para:
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
let newObject = {...object[key]};
newObject.style = {...newObject.style};
newObject.data = {...newObject.data};
output[key] = callback.call(this, newObject);
return output;
}, {});
}
Isso é menos elegante, pois requer saber quais objetos são passados. Existe uma maneira no ES6 de usar a sintaxe de propagação para copiar um objeto em profundidade?
combineReducers
para compor os dois (ou mais) juntos. Se você usar técnicas de redux idiomática, seu problema de clonagem profunda de objetos desaparece.Respostas:
Essa funcionalidade não está embutida no ES6. Acho que você tem algumas opções, dependendo do que deseja fazer.
Se você realmente deseja copiar em profundidade:
cloneDeep
método.Solução alternativa para o seu problema específico (sem cópia profunda)
No entanto, eu acho que se você estiver disposto a mudar algumas coisas, você pode economizar algum trabalho. Presumo que você controle todos os sites de chamada para sua função.
Especifique que todos os retornos de chamada passados para
mapCopy
devem retornar novos objetos em vez de transformar o objeto existente. Por exemplo:Isso é usado
Object.assign
para criar um novo objeto, define propriedadese
desse novo objeto e, em seguida, define um novo título para esse novo objeto. Isso significa que você nunca altera objetos existentes e apenas cria novos quando necessário.mapCopy
pode ser muito simples agora:Basicamente,
mapCopy
é confiar que seus chamadores farão a coisa certa. É por isso que eu disse que isso pressupõe que você controle todos os sites de chamadas.fonte
Em vez disso, use isso para cópia profunda
fonte
De MDN
Pessoalmente, sugiro usar a função cloneDeep de Lodash para clonagem de objetos / matrizes de vários níveis.
Aqui está um exemplo prático:
fonte
Run code snippet
e ele deve ser executado corretamente.Costumo usar isto:
fonte
Usar
JSON.stringify
eJSON.parse
é a melhor maneira. Porque, ao usar o operador spread, não obteremos a resposta eficiente quando o objeto json contiver outro objeto dentro dele. precisamos especificar isso manualmente.fonte
fonte
fonte
fonte
Eu mesmo cheguei a essas respostas no último dia, tentando encontrar uma maneira de copiar estruturas complexas em profundidade, que podem incluir links recursivos. Como não fiquei satisfeito com nada do que foi sugerido antes, implementei esta roda sozinho. E funciona muito bem. Espero que ajude alguém.
Exemplo de uso:
Por favor, olhe https://github.com/latitov/JS_DeepCopy para exemplos ao vivo de como usá-lo, e também deep_print () está lá.
Se você precisar disso rápido, aqui está a fonte da função deep_copy ():
Felicidades@!
fonte
Aqui está o meu algoritmo de cópia profunda.
fonte
Aqui está a função deepClone que lida com todos os tipos de dados primitivos, matrizes, objetos e funções
fonte