Referencias_02Por lo que veo en las dudas de mis cursos y atendiendo consultas de la comunidad, a muchos programadores inexpertos les cuesta de entrada ver la diferencia entre paso por referencia y valor de parámetros de funciones, pero también la diferencia entre una variable, un valor y una referencia a un objeto. Esto suele pasar tanto en JavaScript como en otros lenguajes.

Veamos un caso típico que genera dudas...

Si consideramos este código:

function modificaObjeto(obj2){
  obj2.nombre = "Objeto";
  obj2.valor = 5;
}
 
var obj = {
  nombre: "Pepe",
  valor: 0
};
 
modificaObjeto(obj);

Lo que hacemos es pasar un objeto a la función, y a través del parámetro de ésta modificamos el objeto en si.

Si ahora mostramos ese objeto en la consola veremos que se han modificado sus propiedades, como era de esperar, y que el nombre es "Objeto" y el valor es 5.

Es decir, hemos modificado sus valores originales porque hemos cambiado el objeto en sí al que apunta la variable, pero no a donde apunta ésta.

Parece algo totalmente natural...

Sin embargo, este otro fragmento suele generar muchas más dudas:

function anula(obj2){
  obj2 = null;
}
 
var obj1 = {
  nombre: "Pepe",
  valor: 0
};
 
anula(obj1);

Lo que se hace en la función no es modificar el objeto, sino asignarle un nulo (podría ser otro objeto o valor), al "objeto original".

Si ahora mostramos por consola a obj1, sigue teniendo los valores originales, es decir, se llama "Pepe" y tiene un valor de 0.

Es como si la función no hubiera hecho nada. ¿Por qué?

Lo que ocurre en este fragmento es que cuando anulamos obj2 desde dentro de la función lo que estamos haciendo es poner una referencia al objeto a nulo. Es decir, lo que estamos haciendo es que la variable obj2 que apuntaba al objeto, ahora pase a apuntar a un nulo (u otro objeto o valor), pero no modificamos ni afectamos en absoluto al objeto original.

Para entenderlo mejor, creo que es bueno verlo gráficamente.

Cuando declaramos una variable y la asignamos a un objeto, lo que obtenemos es una referencia a dicho objeto, que podemos representar así:

 Referencias_01

Es decir, la variable obj no es más que una forma de referenciar (o "apuntar", si lo prefieres) a un objeto, que no es más que información en la memoria del ordenador.

Ahora cuando referenciamos a este mismo objeto con otra variable, sea por que la declaramos y la asignamos al mismo objeto, o por que la pasamos como parámetro a una función como en el ejemplo, lo que tendremos serán dos referencias al mismo objeto, así:

 Referencias_02

Esto es lo que ocurre en el primer ejemplo: la variable que apunta a un objeto se la pasamos a la función como parámetro, y acabamos con dos variables apuntando al mismo objeto, una fuera de la función y otra dentro. 

Ahora si asignamos otro valor a una de las variables (segundo ejemplo), lo que hacemos es simplemente destruir la relación que existía entre la variable y el objeto, quedando la situación así:

 Referencias_03

Ahora obj2 puede estar apuntando a otro objeto, contener un número u otro dato básico, incuso un nulo como hacemos en el ejemplo. Pero, sea lo que sea, obj2 ya no "apunta" al objeto original. Ese vínculo se ha roto. Pero no se destruye el objeto en si.

De hecho no se destruye tampoco ni aunque desasignemos también la primera variable: el objeto simplemente quedará "huérfano", sin ninguna referencia apuntando a él,  esperando a que venga el recolector de basura y lo elimine:

 Referencias_04

Por eso, en el ejemplo inicial no se puede eliminar el objeto como se pretendía, ni tampoco acceder de manera alguna a la primera variable desde la función para ponerla a null o asignarle otro valor.

Espero que, si te generaba dudas el concepto, esto sirva para aclararlas :-)

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA