La memoria en JavaScript funciona de la siguiente manera:
Las variables son referencias a un espacio en memoria.
Los navegadores web usan dos tipos de memorias: Stack y Heap.
La memoria Stack es muy rápida, pero sin tanto espacio. Aquí se guardan los valores primitivos (booleanos, strings, números…).
La memoria Heap es más lenta, pero permite guardar enormes cantidades de información (son como los tornados: grandes, lentos y desordenados). En esta memoria guardamos los valores de los objetos
Cómo es el almacenamiento de objetos en JavaScript
Cuando creamos variables en JavaScript (aplicable a casi cualquier otro lenguaje), ejecutamos 2 procesos:
El primero es la inicialización, es decir, le decimos a JS que vamos a crear una nueva variable con un nombre en específico.
let name;
Lo segundo es la asignación: le indicamos a JavaScript que esa variable que generamos con ese nombre en específico tiene un valor.
let name;// Inicialización name ="pepito";// Asignaciónlet age =28;
El nombre de las variables y el valor de estas se almacenan en la memoria stack, excepto cuando trabajamos con objetos.
En memoria, el nombre de las variables apuntan a sus respectivos valores, sin embargo, cuando el valor a almacenar es un objeto, apuntan a otro apuntador (pointer o puntero) y este es el que en realidad apuntará al objeto en sí el cual se encontrará almacenado en la memoria heap.
Cuál es la forma incorrecta de copiar objetos
Si intentamos copiar un objeto en otra variable de esta manera:
Cuando intentemos editar los valores de los atributos del objeto copia, los atributos del objeto original se verán igualmente afectados:
// Objeto original antesconsole.log(juanita);// { age: 15, email: 'juanita@juanita.com' }// Editamos sólo el objeto copianath.age=20;nath.email="nath@email.com"console.log(nath);// { age: 20, email: 'nath@email.com' }// Objeto original después de editar el objeto copia:console.log(juanita);// { age: 20, email: 'nath@email.com' }
Lo anterior sucede porque cuando copiamos un objeto lo que en realidad estamos copiando es su referencia en la memoria, en otras palabras copiamos a su apuntador o pointer. Por ello, al modificar los valores de las propiedades de la copia de un objeto también afectamos al original.
Entonces, ¿Cómo solucionamos esto? Tenemos 2 formas de hacerlo en JavaScript: el shallow copy y el deep copy. Veamos a continuación cómo aplicar el primero. 🤔💪
Funcionamiento de la Memoria y Copia de Objetos en JavaScript
Recursos
Resumen
La memoria en JavaScript funciona de la siguiente manera:
Las variables son referencias a un espacio en memoria.
Los navegadores web usan dos tipos de memorias: Stack y Heap.
La memoria Stack es muy rápida, pero sin tanto espacio. Aquí se guardan los valores primitivos (booleanos, strings, números…).
La memoria Heap es más lenta, pero permite guardar enormes cantidades de información (son como los tornados: grandes, lentos y desordenados). En esta memoria guardamos los valores de los objetos
Cómo es el almacenamiento de objetos en JavaScript
Cuando creamos variables en JavaScript (aplicable a casi cualquier otro lenguaje), ejecutamos 2 procesos:
El primero es la inicialización, es decir, le decimos a JS que vamos a crear una nueva variable con un nombre en específico.
let name;
Lo segundo es la asignación: le indicamos a JavaScript que esa variable que generamos con ese nombre en específico tiene un valor.
let name; // Inicialización
name = "pepito"; // Asignación
let age = 28;
El nombre de las variables y el valor de estas se almacenan en la memoria stack, excepto cuando trabajamos con objetos.
En memoria, el nombre de las variables apuntan a sus respectivos valores, sin embargo, cuando el valor a almacenar es un objeto, apuntan a otro apuntador (pointer o puntero) y este es el que en realidad apuntará al objeto en sí el cual se encontrará almacenado en la memoria heap.
Cuál es la forma incorrecta de copiar objetos
Si intentamos copiar un objeto en otra variable de esta manera:
Cuando intentemos editar los valores de los atributos del objeto copia, los atributos del objeto original se verán igualmente afectados:
// Objeto original antes
console.log(juanita); // { age: 15, email: 'juanita@juanita.com' }
// Editamos sólo el objeto copia
nath.age = 20;
nath.email = "nath@email.com"
console.log(nath); // { age: 20, email: 'nath@email.com' }
// Objeto original después de editar el objeto copia:
console.log(juanita); // { age: 20, email: 'nath@email.com' }
Lo anterior sucede porque cuando copiamos un objeto lo que en realidad estamos copiando es su referencia en la memoria, en otras palabras copiamos a su apuntador o pointer. Por ello, al modificar los valores de las propiedades de la copia de un objeto también afectamos al original.
Entonces, ¿Cómo solucionamos esto? Tenemos 2 formas de hacerlo en JavaScript: el shallow copy y el deep copy. Veamos a continuación cómo aplicar el primero. 🤔💪
🎳 Las variables son referencias a un espacio en memoria.
🎩 Los navegadores web usan dos tipos de memorias: Stack y Heap.
📁 La memoria Stack es muy rápida, pero sin tanto espacio. Aquí se guardan los valores primitivos (booleanos, strings, números...).
🌪 La memoria Heap es más lenta, pero permite guardar enormes cantidades de información (son como los tornados: grandes, lentos y desordenados). En esta memoria guardamos los valores de los objetos ({...}).
.
Entender cómo funciona la memoria en JavaScript no solo será útil para aprender POO, sino también para programación funcional. :wink:
Las variables son una referencia a un espacio en memoria. Dependiendo del tipo de valor que sean serán ubicadas en alguna de las dos tipos de memoria:
Stack - Mucho más rápida, pero sin tanto espacio
Heap - Más lenta, pero con mucho más espacio
Las variables que no tienen un valor de tipo objeto, son almacenadas en la memoria stack. Las variables que tienen como valor un objeto, funcionan de una manera diferente:
El valor (objeto) es guardada en la memoria heap
En la memoria stack se guarda un apuntador (pointer) hacia la memoria heap
Es por esto que cuando nosotros asignamos una variable que tiene como valor un objeto, a una nueva variable, lo unico que hacemos es asignar el apuntador. Es así que al modificar el objeto, en cualquiera de las dos variables, los cambios se reflejan en las dos
En esta clase se está explicando lo que en otros lenguajes explican como copia de valor y copia de referencia.
Cuando copias primitivos (int, string, boolean ) con el signo "=" copias el valor.
Cuando "copias" objetos con el signo "=" no copias el valor, sino la referencia a un lugar en el heap. Por ello al cambiar valores de propiedades del objeto el cambio se reflejará en las 2 variables apuntando al mismo objeto.
Objetos en JavaScript:
Cuando decimos "objeto" nos estamos refiriendo a un objeto literal, un array o una función.
Cualquier otra cosa que no sea un valor primitivo.
Heap (Memoria Dinámica):
Es el área de memoria destinada para almacenar objetos.
Referencia:
La posición de memoria que se usa para acceder a un objeto.
Pero básicamente si el objeto que estás tratando de copiar tiene sólo valores primitivos, podés hacerlo de dos maneras:
let copiaPersona = Object.assign({}, persona);
Esto lo que hace es asignarle a un nuevo objeto vacío todas las propiedades enumerables del otro objeto con sus valores. Obviamente crea un nuevo objeto, una nueva referencia, pero sus propiedades son las mismas.
let otraPersona = { ...persona };
Esto hace básicamente lo mismo. Con el spread operator, estamos llenando un nuevo objeto vacío con todas las propiedades y valores del objeto persona.
Esta forma de copiar objetos se llama shallow copy (un copiado superficial).