Desafio JavaScript
Cópia rasa e aninhada
Enunciado
Crie uma função clonarSuperficial que recebe um objeto e retorna uma cópia rasa usando spread. Em seguida, crie clonarProfundo que também copia objetos aninhados (apenas um nível de profundidade). Demonstre que a cópia rasa compartilha referências aninhadas, enquanto a profunda não. Use JSON.parse(JSON.stringify()) para a cópia profunda? Não, implemente manualmente com spread e verificação de tipo.
Requisitos
clonarSuperficialusa spread para copiar o objetoclonarProfundocopia o primeiro nível e também os objetos aninhados (um nível)- Demonstrar que alterar um objeto aninhado na cópia rasa afeta o original, mas na profunda não
- Imprimir os resultados
Código inicial
function clonarSuperficial(obj) {
// seu código aqui
}
function clonarProfundo(obj) {
// seu código aqui
}
// Teste
const original = { a: 1, b: { c: 2 } };
const copiaRasa = clonarSuperficial(original);
const copiaProfunda = clonarProfundo(original);
copiaRasa.b.c = 99;
copiaProfunda.b.c = 100;
console.log(original.b.c); // 99 (afetado pela rasa)
console.log(copiaRasa.b.c); // 99
console.log(copiaProfunda.b.c); // 100
Saída esperada
99
99
100
Ver dica
Para a cópia profunda, itere sobre as chaves e, se o valor for um objeto (não nulo, não array), use spread para copiá-lo também.
Mostrar solução
function clonarSuperficial(obj) {
return { ...obj }; // cópia rasa: apenas o primeiro nível
}
function clonarProfundo(obj) {
const novo = { ...obj }; // copia o primeiro nível
for (const chave in novo) {
const valor = novo[chave];
if (valor !== null && typeof valor === 'object' && !Array.isArray(valor)) {
novo[chave] = { ...valor }; // copia o objeto aninhado (um nível)
}
}
return novo;
}
// Teste
const original = { a: 1, b: { c: 2 } };
const copiaRasa = clonarSuperficial(original);
const copiaProfunda = clonarProfundo(original);
copiaRasa.b.c = 99; // altera o objeto aninhado compartilhado
copiaProfunda.b.c = 100; // altera apenas a cópia profunda
console.log(original.b.c); // 99
console.log(copiaRasa.b.c); // 99
console.log(copiaProfunda.b.c); // 100
Passo a passo
clonarSuperficialretorna{ ...obj }, que copia as propriedades do primeiro nível. Objetos aninhados continuam sendo a mesma referência.clonarProfundocomeça com uma cópia rasa ({ ...obj }).- O loop
for...inpercorre todas as chaves enumeráveis do novo objeto. - Para cada chave, verificamos se o valor é um objeto não nulo e não array.
- Se for, substituímos por uma nova cópia rasa daquele objeto (
{ ...valor }), quebrando a referência compartilhada. - Retornamos o objeto com aninhamentos copiados.
- Nos testes, alteramos
b.cnas duas cópias e observamos que a original só é afetada pela cópia rasa.
Por que funciona
A cópia rasa copia apenas as referências dos objetos internos. A cópia profunda (um nível) cria novos objetos para cada propriedade que seja um objeto, então alterações nesses objetos não afetam o original. Isso demonstra a diferença fundamental entre shallow e deep copy.
Erros comuns
- Confundir
typeof null:typeof nullé'object', por isso a verificaçãovalor !== nullé obrigatória. - Esquecer de excluir arrays: arrays também são objetos; se não quiser copiá-los como objetos, use
!Array.isArray(valor). - Achar que spread faz cópia profunda:
{ ...obj }não copia aninhamentos; é preciso fazer manualmente.
Outra forma de resolver
Usando structuredClone (disponível em ambientes modernos):
const copiaProfunda = structuredClone(original);
É mais simples e lida com arrays, datas, etc., mas não está disponível em todos os ambientes antigos.
Saída esperada
99
99
100