Funcionamiento de la Memoria y Copia de Objetos en JavaScript
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ó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. 🤔💪
🎳 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:
Gracias por el aporte profesor¡
Yo tengo entendido que a crear la variable se lo conoce como declarar.
const patito
y que inicializar variables es cuando le asignamos algún valor
patito='feo'
Damn, siempre lo digo al revés :sob:
Yo lo tengo entendido como lo dijo el profe jaja.
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
Estar en el curso de Manipulación de Arrays en Js y pasar acá para aclarar una duda sobre el método Map es...simplemente maravilloso
Sí, totalmente de acuerdo, me ayudo bastante a entender
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.
Este curso me está volando la cabeza de una forma increíbleeeeeeee
Esto es lo mas normal que he visto hasta ahora de JS, herencia de C y algo "normal"
No se si aun lo necesites, pero el saber como funcionan los punteros te dan un gran boost en programacion, por ejemplo, podrias manejar Go mas rapido sabiendo este fundamento, te dejo un link a una explicacion en C++ que para mi, es el lenguaje ideal para aprender a manejar punteros
Esta clase explica muchísimos bugs que he tenido en mis proyectos. :D
Lo mismo me pasa a mí no veas el tiempo perdido buscando el porque.... y por fin se entiende.... 👏
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).
No se preocupen amigos, las variables estan a salvo :). Eso solo pasa con los objetos e arrays. pero hay solucion para eso.
Cual?
En realidad está incompleta esa explicación, se puede ver así, para los datos primitivos, los podemos ver como valores, cuando creamos una variables y hacemos una copia del valor, la variable dos es independiente de la uno, cualquier cambio o reasignación que hagamos a una, no afecta a la otra. En cambio con los objetos no, porque ellos no guardan directamente el valor, si no una referencia a la memoria, copiar un objeto (normalmente) solo va a apuntar a la misma referencia, por eso cualquier cambio que se haga, va a afectar al objeto original.
Aqui explican como funciona la pila de ejecucion (callstack de javascript) es buena info para saber como JS procesa nuestro codigo.
genial, gracias
El la pregunta anterior, el profesor dice que los arrays se almacenan en el stack, pero este articulo dice lo siguiente:
What about the memory heap? Oh, the memory heap is where the non-primitive are stored! The big difference between call stack and memory heap is that the heap can store unordered data that grows dynamically — like array and object.
Me equivoqué. Los arrays en este caso funcionan como los objetos, por lo que se almacenan en la memoria heap.
Justamente estaba experimentando con los arrays y funcionan igual que los objetos, así que están en Memory Heap.
El stack es la rom y el heap la ram👍
Los 2 son ram. La diferencia es como dijo, los objetos al heap, todo lo demas al stack
lo que es ROM es localStorage 😅
🧠 Cómo funciona la memoria en JavaScript
Ideas/conceptos claves
Memory Stack es un mecanismo de uso de memoria que permite que la memoria del sistema se use como almacenamiento de datos temporal que se comporta como un búfer de tipo primero en entrar, último en salir (Pila)
Memory Heap es una ubicación en la memoria donde la memoria se puede asignar en acceso aleatorio
Apuntes
Los objetos son referencia a un espacio en memoria
Cuando copiamos un objeto, en realidad estamos copiando su referencia en la memoria
Por ese motivo al modificar la copia estamos modificando también el objeto original
Cuando creamos variables en el lenguaje estamos realizando 2 procesos
Inicialización ⇒ Indicamos al lenguaje que vamos a crear una nueva variable con un nombre
Asignación ⇒ Decir el valor de la variable
El nombre y la variable donde se guardan se llama el memory stack, si bien no se encuentran en el mismo lugar están en la misma memoria
Excepto cuando se trata de objetos
Cuando el valor de las variables es un objeto no es en sí el objeto, sino que es un apuntador (pointer) apuntando donde está guardado el objeto (memory Heap)
Memory Stack se caracteriza por ser rápido, pero tiene un límite corto a comparación del Memory Heap que es más lento, pero tiene mucha más memoria
Por este motivo los valores de los objetos se organizan en el memory Heap y para que se encuentre más rápido solo se guarda la dirección de donde se encuentran en el memory stack
Para poder copiar un objeto se puede realizar de dos maneras
Shallow copy
Deep copy
📌 **RESUMEN:** Al utilizar la memoria en JavaScript en las variables se pueden realizar de dos formas dependiendo del tipo de dato. Si es un dato primitivo se lo pondrá el dato tal cual en el memory Stack, si es un dato de tipo Objeto se guardara la información en el memory Heap que cuenta con más espacio de memoria que el memory Stack. En este último estará la dirección de donde encontrar el objeto conjunto al nombre de la variable.
No es por nada pero Juan David es un crack enseñando, que tremendo profesor!
así lo veo yo:
Los valores de los arrays se almacenan en la memoria Stack ó Heap?
Inicializar una variable es asignarle un valor. Declarar una variable es darle nombre y tipo.
declarar:
let name;
inicializar:
name = 'Rubén';
Estoy también haciendo el curso de estructuras de datos en javascript, y voy mirando clases allí el profe explica el tema de los objetos y que se copia la referencia como el profe JuanDC lo explica muy bien pero notaba que me faltaba algún detalle para asimilarlo bien,... y bueno al ver esta clase era el complemento perfecto ahora entiendo sin lugar a duda este tema que es algo complejo en un principio. Muchas gracias a los dos a Diego de Granda y JuanDC dos grandes profes.... y los cursos de javascript estan siendo increibles... muy buenos.
Lo que en resumen nos dice Juan pero en código muy practico y visible:
classPerson{constructor(name){this.name=name;}}let danny=newPerson('danny');let copy=danny;//Cuando creo la copia y el originalconsole.log(danny);console.log(copy);//cambiar originaldanny.name='juan';console.log(copy);//cambiar copiacopy.name='copia';console.log(danny);