Qué se registra en la consola cuando estás mutando objetos

Muchos desarrolladores no utilizan un depurador mientras desarrollan. En cambio, confían en su viejo amigo console.log().

Es importante tener en cuenta que la consola muestra el valor del objeto que se evalúa en el momento de la primera expansión en la consola.

Primero, déjeme aclarar lo que quiero decir con expansión. Cuando tenemos console.logun objeto (que también cubre matrices), el valor del objeto se contrae. Por ejemplo:

console.log( "users: ", [{name: "John"}]);

La consola del navegador se verá así:

Luego, al hacer clic en el triángulo, el objeto se expande. En ese momento exacto, se evalúa y muestra el valor del objeto.

Profundicemos más en esto y veamos un ejemplo:

En la línea 1 estamos inicializando una nueva usersvariable, que es una matriz de objetos.

En la línea 6 estamos escribiendo el valor de la usersvariable en la consola.

A continuación, iteramos users, verificamos si el usuario es válido y, según la devolución, deshabilitamos al usuario. Por el bien del argumento, supongamos que se ejecutan los validateUser()retornos falsey el código de la línea 10.

Aunque mapestá creando una nueva matriz, cambiar el userobjeto también es cambiar el userobjeto en la usersmatriz. Cambia porque tiene la misma referencia. (Para obtener una mejor explicación de lo que está sucediendo, consulte este artículo).

La pregunta es: ¿qué se mostrará en la consola que se llama en la línea 6?

Cuando abrimos este ejemplo en Chrome y Firefox, el objeto se contrae. Luego, al expandirse, vemos los valores:

Habilitado se establece en false, aunque el valor estaba trueen el momento de la salida. La razón detrás de esto es que el valor del objeto se evalúa la primera vez que hacemos clic para expandir el objeto (lectura diferida).

Nota: Chrome mostrará un ícono de información que dice: "El valor a continuación se evaluó en este momento".

Echemos ahora un vistazo a Safari:

Hm, habilitado se establece en verdadero. Entonces podemos ver que hay algunas inconsistencias entre los navegadores. Safari intentará expandir el objeto automáticamente. Si el objeto / matriz es demasiado grande, colapsará y se comportará de la misma manera que Chrome y Firefox.

Una forma de evitar esto es usar, JSON.stringify(),por ejemplo,

console.log("users", JSON.stringify(users, null, 2));

que producirá la siguiente salida a la consola:

Desafortunadamente, con este enfoque no se puede expandir / contraer un objeto. El valor no cambiará.

Soy un gran admirador del paradigma de programación funcional y las variables inmutables. Para modificar el objeto, crea un clon que luego se modifica. En ese caso, no experimentaría este tipo de "problema". Entonces podríamos escribir algo como esto:

En la función de mapa, ahora clonamos el objeto de usuario que modificamos y devolvemos.

En caso de que se quede con la mutación de objetos, Zoran Jambor agregó otra solución inteligente:

console.log("users", ...users);

Entonces, la matriz de usuarios se destruye y se muestra una lista de objetos en la consola:

Pero aquí también tenemos que tener cuidado. Si el valor del objeto ha sido mutado, la salida de la consola cambiará en la expansión:

En caso de que desee estar absolutamente seguro de que el objeto, que se registró, tiene el mismo valor que tenía durante el archivo console.log, deberá realizar un clon profundo del mismo. Por ejemplo, podríamos usar la siguiente función auxiliar en lugar de escribir directamente en la consola:

En la línea 3, estamos creando un clon profundo del objeto, que da el siguiente resultado:

Ahora, el valor del objeto no cambia al expandirse.

Si usa un depurador, agregar un punto de interrupción a la línea 6 pausará la ejecución. Verá el valor del objeto actual. Si prefiere la consola la mayor parte del tiempo, tenga en cuenta que el objeto / matriz se evalúa en la primera expansión.

Consulte este excelente artículo sobre cómo utilizar el depurador de su navegador.

Gracias por leer. Compártelo con cualquier persona que pueda encontrarlo útil y deja comentarios. (Esta es mi primera historia en Medium y me gustaría seguir escribiendo y mejorar en ella).