Pasar por valor vs. Pasar por referencia
Llamar por valor es la estrategia de evaluación más utilizada: los parámetros formales de una función son copias de los parámetros reales pasados cuando se les llama. La modificación del valor de un parámetro formal no afectará el parámetro real.
Al pasar por referencia (llamar por referencia), los parámetros formales de la función reciben una referencia implícita del parámetro real, en lugar de una copia. Esto significa que si el valor del parámetro de función se modifica, el parámetro real también se modificará. Ambos apuntan al mismo valor.
Pasar por referencia dificulta el seguimiento de la función y, a veces, causa algunos errores sutiles.
Pase por valor ya que las réplicas se clonan cada vez, el rendimiento es menor para algunos tipos complejos. Ambos métodos de valores de aprobación tienen sus propios problemas.
Primero veamos un ejemplo de C para comprender la diferencia entre pasar por valor y referencia:
La copia del código es la siguiente:
Void Modify (int p, int * q)
{
p = 27; // Pase por valor - P es una copia del parámetro real A, solo P se modifica
*q = 27; // Q es una referencia a B, y tanto Q como B se modifican
}
int main ()
{
int a = 1;
int b = 1;
Modificar (a, & b); // un pase por valor, b Pase por referencia,
// a no ha cambiado, B ha cambiado
return (0);
}
Aquí podemos ver:
a => Cuando P se pasa por valor, modificar el valor del parámetro formal P no afecta el parámetro real A, P es solo una copia de a.
B => Q se pasa por referencia. Al modificar el valor del parámetro formal Q, también afecta el valor del parámetro real b.
Explore cómo se pasa el valor JS
El tipo básico de JS se pasa por valor.
La copia del código es la siguiente:
var a = 1;
función foo (x) {
x = 2;
}
foo (a);
console.log (a); // todavía 1, no afectado por la asignación de x = 2
Veamos el objeto:
La copia del código es la siguiente:
var obj = {x: 1};
función foo (o) {
ox = 3;
}
foo (obj);
console.log (obj.x); // 3, modificado!
Explicar O y OBJ son el mismo objeto, y o no es una copia de OBJ. Entonces no se pasa por valor. ¿Pero esto significa que los objetos JS se pasan por referencia? Veamos los siguientes ejemplos:
La copia del código es la siguiente:
var obj = {x: 1};
función foo (o) {
O = 100;
}
foo (obj);
console.log (obj.x); // Todavía 1, OBJ no se ha modificado a 100.
Si se pasa por referencia, modificando el valor del parámetro formal O, debería afectar el parámetro real. Pero modificar el valor de O aquí no afecta a OBJ. Por lo tanto, los objetos en JS no se pasan por referencia. Entonces, ¿cómo se pasa el valor del objeto en JS?
Pase la llamada al compartir
Para ser precisos, los tipos básicos en JS se pasan por valores, y los tipos de objetos se pasan compartiendo (llamada compartiendo, también llamado por objeto y compartido por objeto). Fue propuesto por primera vez por Barbara Liskov. En el lenguaje Glu de 1974. Esta estrategia de evaluación se utiliza en Python, Java, Ruby, JS y otros idiomas.
El punto de esta estrategia es que cuando una función pasa argumento, la función acepta una copia de la referencia de argumento real del objeto (ni una copia del objeto aprobado por valor, ni una referencia implícita aprobada por referencia). La diferencia entre TI y aprobar por referencia es que la asignación de parámetros de función en un pase compartido no afectará el valor del parámetro real. Como en el siguiente ejemplo, el valor de OBJ no puede modificarse modificando el valor del parámetro formal o.
La copia del código es la siguiente:
var obj = {x: 1};
función foo (o) {
O = 100;
}
foo (obj);
console.log (obj.x); // Todavía 1, OBJ no se ha modificado a 100.
Sin embargo, aunque la referencia es una copia, el objeto referenciado es el mismo. Comparten el mismo objeto, por lo que modificar el valor de atributo del objeto de parámetro formal también afectará el valor de atributo del parámetro real.
La copia del código es la siguiente:
var obj = {x: 1};
función foo (o) {
ox = 3;
}
foo (obj);
console.log (obj.x); // 3, modificado!
Para los tipos de objetos, dado que el objeto es mutable, modificar el objeto en sí afectará el intercambio de la copia de referencia y referencia del objeto. Para los tipos básicos, dado que ambos son inmutables, no hay diferencia entre pasar al compartir y pasar por valor (llamada por valor), por lo que los tipos básicos de JS están en línea con el paso por valor y en línea con el paso al compartir.
var a = 1; // 1 es número de tipo, inmutable var b = a; b = 6;
De acuerdo con la estrategia de evaluación aprobada por Shared, A y B son dos referencias diferentes (B es una copia de referencia de A), pero hace referencia al mismo valor. Dado que el tipo básico número 1 aquí es inmutable, no hay diferencia entre pasar por valor y pasar por compartir aquí.
Propiedades inmutables de los tipos básicos
Los tipos básicos son inmutables, y solo los objetos son mutables. Por ejemplo, los valores numéricos 100, los valores booleanos son verdaderos, falsos y modificando estos valores (por ejemplo, convertir 1 en 3, y convertir verdadero en 100) no tiene sentido. Lo que es más fácil de malinterpretar es una cuerda en JS. A veces intentamos "cambiar" el contenido de la cadena, pero en JS, cualquier operación de "modificar" que parece ser un valor de cadena en realidad está creando un nuevo valor de cadena.
La copia del código es la siguiente:
var str = "ABC";
str [0]; // "a"
str [0] = "d";
str; // todavía "ABC"; La tarea no es válida. No hay forma de modificar el contenido de la cadena
El objeto es diferente, el objeto es variable.
La copia del código es la siguiente:
var obj = {x: 1};
obj.x = 100;
var o = obj;
ox = 1;
obj.x; // 1, modificado
o = verdadero;
obj.x; // 1, no cambiará debido a O = verdadero
Aquí se define la variable OBJ, el valor es objeto y luego el valor de la propiedad obj.x se establece en 100. Luego defina otra variable o, y el valor sigue siendo este objeto de objeto. En este momento, los valores de las dos variables obj y o apuntan al mismo objeto (compartiendo una referencia al mismo objeto). Por lo tanto, modificar el contenido del objeto tiene un impacto tanto en OBJ como en O. Sin embargo, el objeto no se pasa por referencia. El valor de O se modifica por O = verdadero y no afectará OBJ.