Pasar variables por referencia en JavaScript
¿Cómo paso variables por referencia en JavaScript?
Tengo tres variables a las que quiero realizar varias operaciones, así que quiero ponerlas en un bucle for y realizar las operaciones en cada una.
Pseudocódigo:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
// Do stuff to the array
makePretty(myArray[x]);
}
// Now do stuff to the updated variables
¿Cuál es la mejor manera de hacer esto?
No hay ningún "pasar por referencia" disponible en JavaScript. Puedes pasar un objeto (es decir, puedes pasar por valor una referencia a un objeto) y luego hacer que una función modifique el contenido del objeto:
function alterObject(obj) {
obj.foo = "goodbye";
}
var myObj = { foo: "hello world" };
alterObject(myObj);
alert(myObj.foo); // "goodbye" instead of "hello world"
Puede iterar sobre las propiedades de una matriz con un índice numérico y modificar cada celda de la matriz, si lo desea.
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 1;
}
Es importante señalar que "pasar por referencia" es un término muy específico. No significa simplemente que sea posible pasar una referencia a un objeto modificable. En cambio, significa que es posible pasar una variable simple de tal manera que permita que una función modifique ese valor en el contexto de llamada . Entonces:
function swap(a, b) {
var tmp = a;
a = b;
b = tmp; //assign tmp to b
}
var x = 1, y = 2;
swap(x, y);
alert("x is " + x + ", y is " + y); // "x is 1, y is 2"
En un lenguaje como C++, es posible hacer eso porque ese lenguaje tiene (más o menos) paso por referencia.
editar : esto recientemente (marzo de 2015) explotó nuevamente en Reddit debido a una publicación de blog similar a la mía que se menciona a continuación, aunque en este caso sobre Java. Mientras leía los comentarios de Reddit, se me ocurrió que gran parte de la confusión surge de la desafortunada colisión que involucra la palabra "referencia". La terminología "pasar por referencia" y "pasar por valor" es anterior al concepto de tener "objetos" con los que trabajar en los lenguajes de programación. En realidad, no se trata en absoluto de objetos; se trata de parámetros de función y, específicamente, de cómo los parámetros de función están "conectados" (o no) al entorno de llamada. En particular, tenga en cuenta que en un verdadero lenguaje de paso por referencia, uno que involucra objetos, aún se tendría la capacidad de modificar el contenido de los objetos , y se vería exactamente igual que en JavaScript. Sin embargo, también se podría modificar la referencia del objeto en el entorno de llamada, y eso es lo clave que no se puede hacer en JavaScript. Un lenguaje de paso por referencia no pasaría la referencia en sí, sino una referencia a la referencia .
editar : aquí hay una publicación de blog sobre el tema. (Tenga en cuenta el comentario de esa publicación que explica que C++ realmente no tiene paso por referencia. Eso es cierto. Sin embargo, lo que sí tiene C++ es la capacidad de crear referencias a variables simples, ya sea explícitamente en el punto de función invocación para crear un puntero, o implícitamente cuando se llama a funciones cuya firma de tipo de argumento requiere que se haga eso. Esas son las cosas clave que JavaScript no admite.)
- Las variables de tipo primitivo, como cadenas y números, siempre se pasan por valor.
- Las matrices y los objetos se pasan por referencia o por valor según estas condiciones:
si está configurando el valor de un objeto o matriz, es Pasar por valor.
object1 = { prop: "car" }; array1 = [1,2,3];
si está cambiando el valor de una propiedad de un objeto o matriz, entonces es Pasar por referencia.
object1.prop = "car"; array1[0] = 9;
Código
function passVar(obj1, obj2, num) {
obj1.prop = "laptop"; // will CHANGE original
obj2 = { prop: "computer" }; //will NOT affect original
num = num + 1; // will NOT affect original
}
var object1 = {
prop: "car"
};
var object2 = {
prop: "bike"
};
var number1 = 10;
passVar(object1, object2, number1);
console.log(object1); // output: Object { prop: "laptop" }
console.log(object2); // output: Object { prop: "bike" }
console.log(number1); // ouput: 10
Solución alternativa para pasar variables como por referencia:
var a = 1;
inc = function(variableName) {
window[variableName] += 1;
};
inc('a');
alert(a); // 2
Y sí, en realidad puedes hacerlo sin acceder a una variable global:
inc = (function () {
var variableName = 0;
var init = function () {
variableName += 1;
alert(variableName);
}
return init;
})();
inc();