Tipos primitivos de JavaScript contra tipos de referencia

Resumen: en este tutorial, aprenderás sobre dos tipos diferentes de datos en JavaScript, incluidos los valores primitivos y de referencia.
JavaScript tiene dos tipos diferentes de valores:
- Valores primitivos
- Valores de referencia
Los valores primitivos son datos atómicos, mientras que los valores de referencia son objetos que pueden constar de varios valores.
Memoria de pila y montón
Cuando declaras variables, el motor de JavaScript les asigna la memoria en dos ubicaciones de memoria: pila (Stack
) y montón (Heap
).
Los datos estáticos son los datos cuyo tamaño se fija en el momento de la compilación. Los datos estáticos incluyen:
- Valores primitivos (
null
,undefined
, boolean, number, string,symbol
, andBigInt
) - Valores de referencia que hacen referencia a objetos.
Debido a que los datos estáticos tienen un tamaño que no cambia, el motor de JavaScript asigna una cantidad fija de espacio de memoria a los datos estáticos y los almacena en la pila.
Por ejemplo, lo siguiente declara dos variables e inicializa sus valores en una cadena literal y un número:
let name = 'John';
let age = 25;
Debido a que name y age son valores primitivos, el motor de JavaScript almacena estas variables en la pila, como se muestra en la siguiente imagen:
Ten en cuenta que las cadenas son objetos en muchos lenguajes de programación, incluidos Java y C#. Sin embargo, las cadenas son valores primitivos en JavaScript.
A diferencia de la pila, JavaScript almacena objetos (y funciones) en el montón. El motor de JavaScript no asigna una cantidad fija de memoria para estos objetos. En cambio, asignará más espacio según sea necesario.
El siguiente ejemplo define las variables de name
, age
y person
:
let name = 'John';
let age = 25;
let person = {
name: 'John',
age: 25,
};
Internamente, el motor de JavaScript asigna la memoria como se muestra en la siguiente imagen:
En esta imagen, JavaScript asigna memoria en la pila para las tres variables name
, age
y person
.
El motor de JavaScript crea un nuevo objeto en la memoria del montón. Además, vincula la variable person en la memoria de la pila con el objeto en la memoria del montón.
Por eso decimos que la variable person es una referencia de un objeto.
Propiedades dinámicas
Un valor de referencia te permite agregar, cambiar o eliminar propiedades en cualquier momento. Por ejemplo:
let person = {
name: 'John',
age: 25,
};
// add the ssn property
person.ssn = '123-45-6789';
// change the name
person.name = 'John Doe';
// delete the age property
delete person.age;
console.log(person);
Resultado:
{ name: 'John Doe', ssn: '123-45-6789' }
A diferencia de un valor de referencia, un valor primitivo no puede tener propiedades. Esto significa que no puedes agregar una propiedad a un valor primitivo.
JavaScript te permite agregar una propiedad a un valor primitivo. Sin embargo, no tendrá ningún efecto. Por ejemplo:
let name = 'John';
name.alias = 'Knight';
console.log(name.alias); // undefined
Resultado:
undefined
En este ejemplo, agregamos la propiedad de alias al valor primitivo de name. Pero cuando accedemos a la propiedad de alias a través del valor primitivo de name, devuelve indefinido (undefined
).
Copiar valores
Cuando asignas un valor primitivo de una variable a otra, el motor de JavaScript crea una copia de ese valor y lo asigna a la variable. Por ejemplo:
let age = 25;
let newAge = age;
En este ejemplo:
- Primero, declaras la variable
age
e inicializas su valor con25
. - En segundo lugar, declaras otra variable
newAge
y asignas age a la variablenewAge
.
Por detrás, el motor de JavaScript crea una copia del valor primitivo 25
y lo asigna a la variable newAge
.
La siguiente imagen ilustra la memoria de pila después de la asignación:
En la memoria de la pila, newAge
y age
son variables separadas. Si cambias el valor de una variable, no afectará a la otra.
Por ejemplo:
let age = 25;
let newAge = age;
newAge = newAge + 1;
console.log(age, newAge);
Cuando asignas un valor de referencia de una variable a otra, el motor de JavaScript crea una referencia para que ambas variables se refieran al mismo objeto en la memoria del montón. Esto significa que, si cambia una variable, afectará a la otra.
Por ejemplo:
let person = {
name: 'John',
age: 25,
};
let member = person;
member.age = 26;
console.log(person);
console.log(member);
Cómo funciona.
Primero, declaras una variable person e inicializas su valor con un objeto con dos propiedades name
y age
.
En segundo lugar, asignas la variable person a la variable member. En la memoria, ambas variables hacen referencia al mismo objeto, como se muestra en la siguiente imagen:
Tercero, cambia la propiedad age del objeto a través de la variable member
:
Dado que tanto la variable person como la member hacen referencia al mismo objeto, el cambio del objeto a través de la variable de member
también se refleja en la variable de person
.
Resumen
- Javascript tiene dos tipos de valores: valores primitivos y valores de referencia.
- Puedes agregar, cambiar o eliminar propiedades a un valor de referencia, mientras que no puedes hacerlo con un valor primitivo.
- Copiar un valor primitivo de una variable a otra crea una copia de valor separada. Significa que cambiar el valor de una variable no afecta a la otra.
- Copiar una referencia de una variable a otra crea una referencia para que dos variables se refieran al mismo objeto. Esto significa que cambiar el objeto a través de una variable se refleja en otra variable.