¿Cómo paso variables por referencia en JavaScript? Tengo 3 variables para las que quiero realizar varias operaciones, por lo que quiero ponerlas en un bucle for y realizar las operaciones para 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 vars
¿Cuál es la mejor manera de hacer esto?
javascript
variables
pass-by-reference
BFTrick
fuente
fuente
makePretty(var1); makePretty(var2); makePretty(var3); ...
arr = [var1, var2, var3]; for (var i = 0, len = arr.length; i < len; i++) { arr[i] = makePretty(arr[i]); }
solo necesita almacenar el valor devuelto pormakePretty
la ranura en la matriz.Respuestas:
No hay "pasar por referencia" disponible en JavaScript. Puede pasar un objeto (es decir, puede pasar por valor una referencia a un objeto) y luego hacer que una función modifique el contenido del objeto:
Puede iterar sobre las propiedades de una matriz con un índice numérico y modificar cada celda de la matriz, si lo desea.
Es importante tener en cuenta que "pasar por referencia" es un término muy específico. No significa simplemente que es 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 la llamada . Entonces:
En un lenguaje como C ++, es posible hacer eso porque ese lenguaje tiene (tipo de) paso por referencia.
editar : esto recientemente (marzo de 2015) explotó en Reddit nuevamente en una publicación de blog similar a la mía mencionada a continuación, aunque en este caso sobre Java. Se me ocurrió mientras leía los comentarios de Reddit que una gran parte de la confusión se deriva de la desafortunada colisión que implica la palabra "referencia". La terminología "pasar por referencia" y "pasar por valor" es anterior al concepto de tener "objetos" para trabajar en lenguajes de programación. Realmente no se trata de objetos en absoluto; se trata de parámetros de función, y específicamente cómo los parámetros de función están "conectados" (o no) al entorno de llamada. En particular,, y se vería exactamente igual que en JavaScript. Sin embargo, uno también podría modificar la referencia de objeto en el entorno de llamada, y eso es lo clave que no 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 a 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 al llamar a funciones cuya firma de tipo de argumento requiere que se haga. Esas son las cosas clave que JavaScript no admite).
fuente
Las matrices y los objetos se pasan por referencia o por valor en función de 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
fuente
Solución alternativa para pasar variables como referencia:
EDITAR
sí, en realidad puedes hacerlo sin acceso global
fuente
Objeto simple
Objeto personalizado
Objeto
rvar
Declaración Variable
O:
Código de prueba
Test Console Result
fuente
Otro enfoque para pasar cualquier variable (local, primitiva) por referencia es envolviendo la variable con cierre "sobre la marcha"
eval
. Esto también funciona con "uso estricto". (Nota: tenga en cuenta queeval
no es amigable con los optimizadores JS, también las comillas faltantes alrededor del nombre de la variable pueden causar resultados impredecibles)Muestra en vivo https://jsfiddle.net/t3k4403w/
fuente
En realidad hay una bonita solución:
fuente
He estado jugando con la sintaxis para hacer este tipo de cosas, pero requiere algunos ayudantes que son un poco inusuales. Comienza sin usar 'var' en absoluto, sino un simple ayudante 'DECLARE' que crea una variable local y define un alcance para ello a través de una devolución de llamada anónima. Al controlar cómo se declaran las variables, podemos elegir envolverlas en objetos para que siempre puedan pasarse por referencia, esencialmente. Esto es similar a una de las respuestas de Eduardo Cuomo anteriores, pero la solución a continuación no requiere el uso de cadenas como identificadores variables. Aquí hay un código mínimo para mostrar el concepto.
fuente
en realidad es muy fácil
El problema es comprender que una vez que pasa los argumentos clásicos, está dentro de otra zona de solo lectura.
soluciones es pasar los argumentos usando el diseño orientado a objetos de JavaScript,
es lo mismo que poner los argumentos en una variable global / de ámbito, pero mejor ...
También puede prometer cosas para disfrutar de la conocida cadena: aquí está todo, con una estructura prometedora
o mejor aún..
action.setArg(["empty-array"],"some string",0x100,"last argument").call()
fuente
this.arg
solo funciona conaction
instancia. Esto no funciona.Personalmente no me gusta la funcionalidad "pasar por referencia" que ofrecen varios lenguajes de programación. Quizás es porque estoy descubriendo los conceptos de programación funcional, pero siempre me pone la piel de gallina cuando veo funciones que causan efectos secundarios (como la manipulación de parámetros pasados por referencia). Yo personalmente abrazo firmemente el principio de "responsabilidad única".
En mi humilde opinión, una función debe devolver solo un resultado / valor utilizando la palabra clave return. En lugar de modificar un parámetro / argumento, simplemente devolvería el valor modificado del parámetro / argumento y dejaría cualquier reasignación deseada al código de llamada.
Pero a veces (con suerte muy raramente), es necesario devolver dos o más valores de resultado de la misma función. En ese caso, optaría por incluir todos esos valores resultantes en una sola estructura u objeto. Nuevamente, el procesamiento de cualquier reasignación debe corresponder al código de llamada.
Ejemplo:
Supongamos que se admiten parámetros de paso mediante el uso de una palabra clave especial como 'ref' en la lista de argumentos. Mi código podría verse así:
En cambio, preferiría hacer algo como esto:
Cuando necesito escribir una función que devuelve múltiples valores, tampoco usaría parámetros pasados por referencia. Entonces evitaría un código como este:
En cambio, preferiría devolver ambos valores nuevos dentro de un objeto, como este:
Estos ejemplos de código están bastante simplificados, pero demuestran más o menos cómo yo personalmente manejaría tales cosas. Me ayuda a mantener varias responsabilidades en el lugar correcto.
Feliz codificación :)
fuente
findStuff
devuelto simplemente la matriz resultante. Usted también tiene que declarar unafoundArray
variable, por lo que iba a asignar directamente la matriz resultante a la misma:var foundArray = findStuff(inArray); if (foundArray.length > 0) { /* process foundArray */ }
. Esto 1) haría que el código de llamada sea más legible / comprensible, y 2) simplifique considerablemente la funcionalidad interna (y, por lo tanto, también la capacidad de prueba) delfindStuff
método, haciéndolo mucho más flexible en diferentes (re) casos / escenarios de uso.Javascript puede modificar elementos de la matriz dentro de una función (se pasa como referencia al objeto / matriz).
Aquí hay otro ejemplo:
fuente
JS no es de tipo fuerte, le permite resolver problemas de muchas maneras diferentes, como parece en este dibujo.
Sin embargo, desde el punto de vista del mantenimiento, tendría que estar de acuerdo con Bart Hofland. La función debería hacer que args haga algo y devuelva el resultado. Haciéndolos fácilmente reutilizables.
Si cree que las variables deben pasarse por referencia, es mejor que las convierta en objetos en mi humilde opinión.
fuente
Dejando a un lado la discusión de paso por referencia, aquellos que todavía buscan una solución a la pregunta planteada podrían usar:
fuente
Sé exactamente a que te refieres. Lo mismo en Swift no será un problema. La conclusión es el uso
let
novar
.El hecho de que las primitivas pasen por valor, pero el hecho de que el valor de
var i
en el punto de iteración no se copia en la función anónima es bastante sorprendente, por decir lo menos.fuente