|
| 1 | +/* Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24 |
| 2 | +Ejercicio */ |
| 3 | + |
| 4 | +/* |
| 5 | + * EJERCICIO: |
| 6 | + * - Muestra ejemplos de asignación de variables "por valor" y "por referencia", según |
| 7 | + * su tipo de dato. |
| 8 | + * - Muestra ejemplos de funciones con variables que se les pasan "por valor" y |
| 9 | + * "por referencia", y cómo se comportan en cada caso en el momento de ser modificadas. |
| 10 | + * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes) |
| 11 | + * |
| 12 | + * DIFICULTAD EXTRA (opcional): |
| 13 | + * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente. |
| 14 | + * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia. |
| 15 | + * Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno |
| 16 | + * se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las |
| 17 | + * variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas. |
| 18 | + * Comprueba también que se ha conservado el valor original en las primeras. |
| 19 | + */ |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | +// ASIGNACIÓN VARIABLES "POR VALOR" |
| 24 | + |
| 25 | +/* |
| 26 | +Esto aplica con tipos de datos primitivos: String, Number, Null, Boolean, Undefined (Revisar: BigInt y Symbol) |
| 27 | +
|
| 28 | +Este tipo de asignación basicamente cuando se crea una variable "a" y se le asigna valor x, depués se crea una |
| 29 | +variable "b" y se le asigna la variable "a", practicamente se está haciendo una copia de la variable "a", |
| 30 | +para asignarsela a "b". |
| 31 | +
|
| 32 | +La variable "a" está en un espacio de memoria y la variable "b" está en otro espacio de memoria, por ello es que aunque |
| 33 | +después se cambie el valor de la variable "a" por z, el valor que está en la variable "b" seguirá siendo el mismo que ya |
| 34 | +tenia asignado una copia (x). |
| 35 | +*/ |
| 36 | + |
| 37 | +//POR VALOR |
| 38 | +let var1 = "México"; |
| 39 | +let var2 = "España"; |
| 40 | +console.log(var1); // México |
| 41 | +console.log(var2); // España |
| 42 | + |
| 43 | +let var3 = var1; //var3 ahora se le asignó una "copia" del valor de la var1 entonces var3 = "México" |
| 44 | + |
| 45 | +console.log(var3 == var1) |
| 46 | +/* Resultado true, porque a pesar de que están en distintos espacios de memoria, tienen el mismo valor con el mismo |
| 47 | +tipo de dato. Ya que los datos primitivos se asignan "por valor". |
| 48 | +*/ |
| 49 | +var3 = "Francia"; //var3 ahora se le asignó un nuevo valor, ahora var3 = "Francia" |
| 50 | +console.log(var3); |
| 51 | +console.log(var1); //var1 sigue valiendo "México". |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +//ASIGNACIÓN DE VARIABLES "POR REFERENCIA" |
| 56 | + |
| 57 | +/* |
| 58 | +Esto aplica con tipos de datos compuestos: Object (Objects, Functions, Arrays, Set, Etc...) |
| 59 | +
|
| 60 | +Basicamente cuando se crea un arreglo o un objeto con ciertos valores como nombre: Daniel y edad: 27 y se asigna a |
| 61 | +una variable. |
| 62 | +
|
| 63 | +Por ejemplo obj1, como tal obj1 no tiene asignados lo valores nombre y edad, lo que tienen asignado literalmente es la |
| 64 | +dirección en memoria donde se encuentran esos datos. |
| 65 | +Ahora si se crea otra variable como obj2, a la cual se le asigna la variable obj1 (let obj2 = obj1), entonces en este caso |
| 66 | +no se hace una copia de los valores dentro del objeto, se hace una copia de la dirección en memoria donde se encuentran |
| 67 | +los valores. Así que en dado caso en el que se cambie algun valor del objeto obj1, este tambien se verá reflejado en obj2. |
| 68 | +
|
| 69 | +Esto es porque no se copia directamente el valor sino la dirección en memoria donde se encuentran los valores. |
| 70 | +*/ |
| 71 | + |
| 72 | +//EJEMPLO |
| 73 | +let arr = ["Daniel", "Gustavo", "Jannet"]; |
| 74 | +let arr2 = arr; |
| 75 | + |
| 76 | +arr2.push("Daneri"); |
| 77 | + |
| 78 | +console.log(arr); |
| 79 | +console.log(arr2); |
| 80 | + |
| 81 | +let arr3 = arr2; |
| 82 | +arr3.push("Zulema") |
| 83 | + |
| 84 | +console.log("arr3"); |
| 85 | +console.log(arr3); |
| 86 | + |
| 87 | +console.log("arr"); |
| 88 | +console.log(arr); |
| 89 | + |
| 90 | +console.log("arr2"); |
| 91 | +console.log(arr2); |
| 92 | + |
| 93 | +//EJEMPLO |
| 94 | +let obj1 = { |
| 95 | + nombre: "Daniel", |
| 96 | + edad: 27 |
| 97 | +} |
| 98 | +console.log(obj1); |
| 99 | + |
| 100 | +let obj3 = obj1; |
| 101 | +console.log(obj3); |
| 102 | + |
| 103 | +obj3.nombre = "Alejandra"; |
| 104 | +console.log(obj3); |
| 105 | +console.log(obj1); |
| 106 | +console.log(obj1 == obj3); |
| 107 | +//Resultado true, porque las dos variables apuntan a la misma dirección en memoria (espacio en memoria). |
| 108 | + |
| 109 | + |
| 110 | +let obj2 = { |
| 111 | + nombre: "Daniel", |
| 112 | + edad: 27 |
| 113 | +} |
| 114 | +console.log(obj2 == obj1); |
| 115 | +/* Resultado false, porque a pesar de tener los mismos valores, estos están en distintas direcciones en memoria |
| 116 | +(espacios de memoria). |
| 117 | +
|
| 118 | +Los objetos compuestos se asignan "por referencia", unicamente son iguales cuando se encuentran en el mismo |
| 119 | +espacio de memoria ya que comparten los mismo valores |
| 120 | +*/ |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | +//FUNCIONES CON ASIGNACIÓN POR VALOR Y POR REFERENCIA. |
| 126 | + |
| 127 | +//FUNCION POR VALOR |
| 128 | + |
| 129 | +/* |
| 130 | +Cuando pasamos valores primitivos a una función, ésta copia los valores en sus parámetros. |
| 131 | +Es efectivamente lo mismo que usar = |
| 132 | +
|
| 133 | +Todas las operaciones que se realizan dentro de la función con las copias de los valores de esas variables |
| 134 | +no afecta en nada los valores que se encuentran fuera de la función. |
| 135 | +*/ |
| 136 | + |
| 137 | +let num1 = 50, num2 = 34; |
| 138 | + |
| 139 | +function sumar(x, y) { |
| 140 | + console.log("Suma de los parametros antes de cambiar su valor dentro de la función " + (x + y)); //84 |
| 141 | + x = 20; |
| 142 | + y = 30; |
| 143 | + return x + y; |
| 144 | +} |
| 145 | +console.log(`Suma de los parametros dentro de la función ${sumar(num1, num2)}`); //50 |
| 146 | +console.log(`Suma de variable fuera de la función ${num1 + num2}`); //84 |
| 147 | + |
| 148 | +/* Como se ve en el ejemplo, la variables fuera de la función no se ven afectadas ya que x & y hacen una copia de los valores |
| 149 | +que tienen num1 y num2. */ |
| 150 | + |
| 151 | + |
| 152 | + |
| 153 | +// FUNCION REFERENCIA |
| 154 | + |
| 155 | +/* |
| 156 | +Cuando pasamos valores compuestos a una función, de la misma forma solo se hace una copia de la dirección en memoria de |
| 157 | +donde se encuentran los valores reales. |
| 158 | +
|
| 159 | +Todas las operaciones que se realizan dentro de la función con las variables o parametros que contengan |
| 160 | +las copias de la dirección de referencia, se veran afectadas dentro y fuera de la función. |
| 161 | +
|
| 162 | +Esto se puede evitar realizando cierta operación para evitar que los objetos modificados dentro de la función |
| 163 | +no afecten a los objetos fuera de esta. Y esto se logra haciendo una copia legitima del objeto en cuestion. |
| 164 | +*/ |
| 165 | + |
| 166 | +//FUNCION REFERENCIA NORMAL |
| 167 | +let array = ["Daniel", "Gustavo", "Jannet"]; |
| 168 | +function reff() { |
| 169 | + let array2 = array; |
| 170 | + array2.push("Rosalí"); |
| 171 | + return array2; |
| 172 | +} |
| 173 | +console.log(reff()); //[ 'Daniel', 'Gustavo', 'Jannet', 'Rosalí' ] |
| 174 | +console.log(array); //[ 'Daniel', 'Gustavo', 'Jannet', 'Rosalí' ] |
| 175 | + |
| 176 | + |
| 177 | +//Ejemplo por referencia |
| 178 | +function cambiaLaEdadYLaReferencia(persona) { |
| 179 | + persona.edad = 25; |
| 180 | + persona = { |
| 181 | + nombre: 'John', |
| 182 | + edad: 50 |
| 183 | + }; |
| 184 | + return persona; |
| 185 | +} |
| 186 | +let persona1 = { |
| 187 | + nombre: 'Claudia', |
| 188 | + edad: 31 |
| 189 | +}; |
| 190 | +let persona2 = cambiaLaEdadYLaReferencia(persona1); |
| 191 | +console.log(persona1); // -> ? |
| 192 | +console.log(persona2); // -> ? |
| 193 | + |
| 194 | + |
| 195 | +//Ejemplo copia de objeto: |
| 196 | +let arreglo = ["HTML", "CSS", "JAVASCRIPT"]; |
| 197 | +function lenguaje(dev) { |
| 198 | + //Convertimos el objeto en cadena y despues en objeto nuevamente para hacer una copia del objeto completo |
| 199 | + let nuevaPersona = JSON.parse(JSON.stringify(dev)); |
| 200 | + nuevaPersona.push("PHP"); |
| 201 | + console.log(nuevaPersona); |
| 202 | + //De esta forma cuando se modifica el nuevo objeto dentro de la función, no afecta al objeto fuera de la misma |
| 203 | +} |
| 204 | +lenguaje(arreglo); //[ 'HTML', 'CSS', 'JAVASCRIPT', 'PHP' ] |
| 205 | +console.log(arreglo);//[ 'HTML', 'CSS', 'JAVASCRIPT' |
| 206 | + |
| 207 | +/* |
| 208 | + * DIFICULTAD EXTRA (opcional): |
| 209 | + * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente. |
| 210 | + * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia. |
| 211 | + * |
| 212 | + * |
| 213 | + * Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno |
| 214 | + * se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las |
| 215 | + * variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas. |
| 216 | + * Comprueba también que se ha conservado el valor original en las primeras. |
| 217 | + */ |
| 218 | + |
| 219 | +let nombre = "Daniel"; |
| 220 | +let apellido = "Martínez"; |
| 221 | + |
| 222 | +function progValor(nombre, apellido) { |
| 223 | + let extra = nombre |
| 224 | + nombre = apellido |
| 225 | + apellido = extra |
| 226 | + return nombre + " " + apellido; |
| 227 | +} |
| 228 | +console.log(progValor(nombre, apellido)); |
| 229 | +console.log(nombre, apellido); |
| 230 | + |
| 231 | +/* |
| 232 | +NOTA: El concepto de paso por referencia en JavaScript es consistente tanto dentro como fuera de las funciones. |
| 233 | +Siempre se manejan referencias a objetos, no copias de los objetos en sí. Las asignaciones dentro de una |
| 234 | +función solo afectan a las variables locales a menos que se modifiquen directamente los objetos referenciados |
| 235 | +(como agregar elementos a un array, por ejemplo). |
| 236 | +*/ |
| 237 | + |
| 238 | + |
| 239 | +let listaNombre = ["Jim", "Pam", "Dwigth"]; |
| 240 | +let listName = ["Manuel", "Fidencio", "Jose"]; |
| 241 | + |
| 242 | +function progReferencia(listaNombre, listaName) { |
| 243 | + let extra = listaNombre; |
| 244 | + listaNombre = listName; |
| 245 | + listaName = extra; |
| 246 | + return [listaNombre, listaName]; |
| 247 | +} |
| 248 | +console.log(progReferencia(listaNombre, listName)); |
| 249 | +console.log(listaNombre, listName); |
| 250 | + |
| 251 | + |
| 252 | + |
| 253 | + |
| 254 | + |
| 255 | + |
| 256 | + |
| 257 | + |
| 258 | + |
| 259 | + |
| 260 | + |
| 261 | + |
| 262 | + |
| 263 | + |
| 264 | + |
| 265 | + |
| 266 | + |
| 267 | + |
| 268 | + |
| 269 | + |
| 270 | + |
| 271 | + |
| 272 | + |
0 commit comments