Diferença entre angular.copy e Angular.extend em objetos JavaScript

image_pdfimage_print

O problema de cópia de objeto em JavaScript por referência ou por valor, que pode confundir muitos.

A regra em JavaScript, quando nos referimos a operação com objeto é a cópia por referência. No entanto, por vezes é necessário obtermos uma mera cópia.

Eis que o AngularJS tem suas próprias funções de manipulação de objetos. Iremos rapidamente tratar de duas. O copy e o extend.

O copy é muito importante entender, visto que cria um cópia do objeto alvo. O que faz possível duplicar o objeto. Já o extend é para cópia de propriedades de um objeto para outro. Importante se atentar que o mesmo cópia propriedades existente em um para o outro, mantendo intacta aquelas existentes somente no objeto receptor. Podemos verificar mais detalhes no exemplo abaixo:

#Primeiro objeto
a = {"a":0,"b":1};

#Segundo objeto
b = angular.copy(a);

#Adiciona um atributo ao segundo objeto
b.c = 2;

#Nao interfere no primeiro objeto. Saída igual {"a":0,"b":1,"c":2};
console.log(b);

#Nao foi alterada pela operacao no segundo objeto. Saída igual {"a":0,"b":1};
console.log(a);

#Terceiro objeto
c = {"d":3};

#Copia as propriedades existentes no primeiro objeto para o terceiro objeto
angular.extend(c,a);

#Nao interfere no primeiro objeto. Saída igual {"a":0,"b":1,"d":3};
console.log(c);

#Nao foi alterada pela operacao no segundo objeto. Saída igual {"a":0,"b":1};
console.log(a);

No entanto, muito cuidado no uso do extend, visto que a sintaxe abaixo irá gerar um resultado de cópia por referência e não é seu uso correto. É justamente um erro de uso e que pode gerar problemas para encontrar o erro:

#Primeiro objeto
a = {"a":0,"b":1};

#Segundo objeto
b = angular.extend(a);

#Adiciona um atributo ao segundo objeto
b.c = 2;

#Interfere no primeiro objeto. Saída igual {"a":0,"b":1,"c":2};
console.log(b);

#Foi alterada pela operacao no segundo objeto. Saída igual {"a":0,"b":1,"c":2};
console.log(a);

Assim como o seguinte erro irá gerar comportamento não esperado

#Primeiro objeto
a = {"a":0,"b":1};

#Segundo objeto
b = {"d":3}

#Irá sobreescrever b, visto que o método foi utilizado com a sintaxe errada. 
b = angular.extend(a);

#Adiciona um atributo ao segundo objeto
b.c = 2;

#Interfere no primeiro objeto. Saída igual {"a":0,"b":1,"c":2};
console.log(b);

#Foi alterada pela operacao no segundo objeto. Saída igual {"a":0,"b":1,"c":2};
console.log(a);

Gostou? Tire um minutinho e dê sua contribuição para Drall Dev Community no Patreon!