Si JavaScript es un pase por referencia o un pase por tipo de valor

  1. Los tipos de datos primitivos en JavaScript se pasan por valor
  2. Los valores no primitivos en JavaScript se pasan por referencia
  3. JavaScript es tanto pasar por valor como pasar por referencia

Antes de profundizar en si el lenguaje de programación JavaScript es un tipo de paso por referencia o no, veamos primero la diferencia entre paso por valor y paso por referencia.

Por lo general, estas cosas entran en escena cuando realizamos operaciones de asignación o tratamos con las funciones mismas. Dado que la mayoría de las veces, realizamos operaciones de asignación, creamos varias funciones y pasamos múltiples variables a estas funciones, saber cómo funcionan estas cosas internamente nos daría una comprensión más profunda del lenguaje de programación.

Siempre que asignamos o pasamos el valor de una variable a otra variable o función, se conoce como pasar por valor. Cuando asignamos o pasamos la dirección de una variable a otra variable o función, se conoce como pasar por referencia.

Ahora que hemos visto la definición básica de los tipos de referencia de paso por valor y paso por referencia, comprendamos mejor cómo se utilizan en los siguientes ejemplos.

Los tipos de datos primitivos en JavaScript se pasan por valor

Tenga en cuenta que hay dos tipos de tipos de datos en JavaScript: el tipo de datos primitivo y el tipo de datos no primitivo. Los tipos de datos primitivos constan de números, booleanos, cadenas, indefinidos y nulos.

Estos tipos de datos no tienen métodos predefinidos como los que tenemos en objetos o matrices. Los tipos de datos primitivos son inmutables; esto significa que siempre que almacene o asigne el valor de una variable primitiva a otra y haga algunas modificaciones al valor de la segunda variable, el valor de la primera variable no cambiará. Permanecerá como está hasta y a menos que cambie el valor de esa variable en sí. Solo entonces se modificará la segunda variable.

Puede encontrar más información relacionada con los tipos de datos primitivos en MDN.

// Example 1
let a = 10;
let b = a;
b = b + 1;

console.log(a);
console.log(b);


// Example 2
let name = "Google";

let greet = (val) => {
   val = "Hi " + name +"!";
   return val;
 }

console.log(name);
console.log(greet(name));

Producción:

10
11
Google
Hi Google!

El código anterior se puede entender mejor con la ayuda de la siguiente ilustración. Tenga en cuenta que solo explica el primer ejemplo de código; el segundo ejemplo funcionará básicamente de la misma manera que el ejemplo uno.

visualización de ejemplo de tipo primitivo

En nuestro primer ejemplo, tenemos dos variables: a y b. Hemos asignado un valor numérico de 10 a nuestra variable a; esto asignará un espacio para la variable a en la memoria, representada por el color amarillo que tiene una dirección 0x01 (que es solo una dirección arbitraria tomada para este ejemplo).

Luego, asignamos la variable a a la variable b. Este proceso asignará el nuevo espacio de memoria para la variable b. Aquí, almacenará el valor de la variable a, que es 10.

En el ejemplo anterior, podemos ver claramente que la dirección de ambas variables a y b es diferente, lo que significa que han asignado diferentes espacios en la memoria. Este resultado implica que siempre que cambie o modifique el valor de la variable b como b = b + 1, el valor dentro de la variable a no cambiará. Solo cambiará el valor de la variable b, y se convertirá en 11 ya que lo estamos incrementando en uno.

En nuestro segundo ejemplo, tenemos una variable name que tiene un valor Google dentro. También tenemos una función llamada saludar (), que toma un valor de cadena como argumento y devuelve una nueva cadena. Como argumento de esta función, pasamos la variable a (observe que pasar una variable significa pasar su valor y no su dirección). El valor de Google se almacenará dentro de la variable local de la función denominada val.

Actualmente, la variable val tiene el valor Google. En la función, cambiamos este valor a Hi Google!. y luego devolver este valor. Ahora, si genera tanto el valor de las variables name como las funciones, junto con el valor devuelto, ambos serán diferentes. Las variables name permanecen sin cambios porque ambas variables name y val se almacenan en ubicaciones diferentes, y solo estamos pasando el valor Google a la función y la dirección.

Anteriormente, hemos visto la definición de pasar por valor, que decía que solo pasamos el valor de la variable durante una asignación o mientras lo pasamos a una función. Los dos ejemplos anteriores lo demostraron en la práctica.

Los valores no primitivos en JavaScript se pasan por referencia

Los tipos de datos no primitivos consisten en matrices, objetos o clases. Estos tipos de datos tienen funciones integradas predefinidas que nos permiten manipular los datos dentro de las matrices o los objetos.

Los tipos de datos primitivos son mutables; esto significa que los tipos de datos que se pueden modificar posteriormente se conocen como mutables. Además, los tipos de datos no primitivos se llaman por referencia. Entendamos esto con el siguiente ejemplo.

let a = [1,2];
let b = a;
b.push(3);

console.log(a)
console.log(b)

Producción:

[ 1, 2, 3 ]
[ 1, 2, 3 ]

La imagen del ejemplo anterior se muestra a continuación.

ejemplo de tipo no premitivo

En este ejemplo, creamos un array a con dos elementos: [1,2]. Dado que un array es un tipo de datos no primitivo, la variable a no almacenará todos los elementos del array. En cambio, los valores [1,2] se almacenarán en otra ubicación de la memoria. En este caso, la dirección inicial de esa matriz, en este caso, 0x01, se almacenará en la variable a, como se muestra en el diagrama anterior. Dado que la variable a tiene la dirección donde se almacenan los elementos reales del array, apuntará a esa ubicación.

Cuando asignamos la variable a a la variable b, estamos almacenando la dirección presente dentro de a en la variable b. Ahora, la variable b también apuntará a la misma ubicación de memoria, 0x011, que la de la variable a, ya que ambas tienen la misma dirección de memoria. Entonces, si cambia los elementos de un array apuntada por b, entonces a también se verá afectado porque ambos apuntan a la misma ubicación.

Aquí, estamos insertando un nuevo elemento en el array usando la variable b como b.push(3). Ahora, la variable b recorrerá toda el array desde el primer elemento, 1, hasta el último elemento, 2. Después del último elemento, insertará el nuevo elemento 3 en el array. Si imprime las variables a y b, verá que ambas mostrarán el mismo valor que [1,2,3] debido a la referenciación.

Esto se conoce como paso por referencia porque estamos pasando la dirección de memoria en sí y no el valor.

JavaScript es tanto pasar por valor como pasar por referencia

El lenguaje de programación JavaScript admite tanto el paso por valor como el paso por referencia. Los valores primitivos como números, booleanos, cadenas, indefinidos y nulos se pasan por valores. Los tipos no primitivos, como matrices, objetos y clases, se pasan por referencia.