Por favor considere el siguiente código:
function func1(a, b) { let args = arguments; console.log(args); return function() { for (let i in args) { console.log(args[i], a, b) args[i] += (a + b); console.log("|") console.log(args[i], a, b); console.log("end") } } } func1(2, 4)();Esto da la siguiente salida
2 2 4 | 8 8 4 end 4 8 4 | 16 8 16 end ¿Cómo cambia aquí el valor de a, b ?
En modo suelto,¹ la pseudo-matriz de arguments tiene un enlace directo a los parámetros formales de una función. Aquí hay un ejemplo más simple:
function example(a) { console.log("before, a = " + a); ++arguments[0]; console.log("after, a = " + a); } example(1); Como puede ver, ++arguments[0] modificó el valor de a .
Este enlace espeluznante se elimina en modo estricto , que debe ser utilizado por todo el código nuevo (explícitamente o mediante el uso de módulos):
"use strict"; function example(a) { console.log("before, a = " + a); ++arguments[0]; console.log("after, a = " + a); } example(1);En un comentario, has preguntado:
Entonces, aunque si clonamos los argumentos, ¿todavía tiene un enlace en vivo a su clon?
Nada en el código de la pregunta clona el objeto de arguments . let args = arguments; solo apunta args al objeto, no lo copia . Empiezas con:
+--------------------------+
argumentos:−−−−−>| (objeto de argumentos) |
+--------------------------+
| (enlace espeluznante a a, b) |
+--------------------------+
Entonces let args = arguments; solo hace esto:
argumentos:−−+
|
| +--------------------------+
+−−>| (objeto de argumentos) |
| +--------------------------+
| | (enlace espeluznante a a, b) |
argumentos:-------+ +-------------------------+
Sigue siendo el mismo objeto.
Si lo copia (solo una copia superficial está bien), entonces puede modificar la copia sin afectar a y b :
let args = [...arguments]; // Or `= Array.prototype.slice.call(arguments);`Entonces obtienes:
+--------------------------+
argumentos:−−−−−>| (objeto de argumentos) |
+--------------------------+
| (enlace espeluznante a a, b) |
+--------------------------+
+--------------------------+
argumentos:−−−−−−−−−>| (matriz) |
+--------------------------+
| 0: valor copiado de `a` |
| 1: valor copiado de `b` |
+--------------------------+
... y los cambios en los args no se muestran en a y b .
¹ el modo suelto a menudo, lamentablemente, se llama modo "descuidado"
function func1(a, b) { let args = arguments; console.log(args); return function () { for (let i in args) // it runs 2 times { console.log(args[i], a, b) args[i] += (a + b); // first time args[0] (this is the reference to 'a') set to 2+2+4 = 8 // second time args[1] (it is the reference to b) set to 4+8+4 = 16 console.log("|") console.log(args[i], a, b); console.log("end") } }}func1(2, 4)();args[0] se refiere a a y args[0] se refiere a b
porque args es un objeto que se almacena en otro lugar en el entorno del navegador/nodo
consulte cómo actúa la referencia en js usando este video