30.10.2021 a las 18:35
Aprenderás a cómo copiar variables y objetos en JavaScript tanto por referencia como por valor
Cuando aterricé al mundo de la programación, una cosa que no asimilé instantáneamente fue la diferencia entre copiar por valor o por referencia.
En VB6, que fue con el lenguaje que comencé a programar se podía especificar cuando copiabas una variable si lo querías hacer por referencia (byRef) o por valor (byVal).
Lo que significa es que si quieres copiar una variable lo puedes hacer apuntando a su dirección en memoria (por referencia), o creando la variable nueva y asignándole el valor de la cúal quieres copiar.
Cuando copias datos de tipo primitivos, la copia siempre erá por valor, con lo que no tendrás daños colaterales al copiar datos primitivos en tu código.
Los datos primitivos son:
En el caso de los objetos y arrays, la copia siempre será por referencia. Te lo explico con un ejemplo:
const uno:number[] = [1,2,3,4,5]; let dos:number[]=uno; dos[1]=1; console.log(dos); //[1,1,3,4,5] console.log(uno); //[1,1,3,4,5]
Vemos que como la copia es por referencia también cambia el array llamado uno.
El método create de Object nos permite hacer una copia profunda de objetos, mira:
const bike1 = {name:"BH", whellsSize:[17,26,27.5,29]}; const bike2 = Object.assign(Object.create(bike1),bike1); bike2.whellsSize=29; console.log(bike1); //[LOG:]{name:"BH", whellsSize:[17,26,27.5,29]} console.log(bike2); //[LOG:]{name:"BH", whellsSize:29}
Básicamente lo que hacemos primero es parsear el objeto a string y después lo pasamos a un objeto.
Como verás más adelante, los tipos puros (string, number...) siempre son copiados por valor.
const bike1 = {name:"BH", whellsSize:[17,26,27.5,29]}; const bike2 = JSON.parse(JSON.stringify(bike1)); bike2.whellsSize=29; console.log(bike1); //[LOG:]{name:"BH", whellsSize:[17,26,27.5,29]} console.log(bike2); //[LOG:]{name:"BH", whellsSize:29}
Para hacer una copia profunda, ahora tenemos de forma nativa el método structuredClone
Para usar dicho método tan fácil como:
objetoACopiar=structuredClone(objetoOrigen)
Te recomiendo que uses 👉structuredClone👈 para copiar objetos o array de forma profunda, ya cuenta con un gran soporte.
Con el spread operator no harás copias profundas.
Con copia profunda me refiero a que si tienes un objeto donde uno de sus campos es otro objeto o un array no se copia por valor, si no por referencia.
Con la llegada de ECMAScript v6, se introdujo el spread operator, que además de copia de array o objetos también te permite la desestructuración, que es muy útil cuando la comprendes.
Pues lo dicho, con el spread operator se haría así:
const uno:number[] = [1,2,3,4,5]; let dos:number[]=[...uno]; dos[1]=1; console.log(dos); //[1,1,3,4,5] console.log(uno); //[1,2,3,4,5]
No todo iba a ser bueno con el spread operator, el problema que tiene es que como estamos haciendo una copia completa del elemento pues vamos a consumir más memoria.
El ejemplo que he puesto es un poco tonto, pero imagina que tuvieras un array MUY grande de objetos y sólo quisiera cambiar una propidad de cada objeto, al hacerlo con el spread operator harías una copia completa del array original.
Hasta luego 🖖