Hvad bliver logget i konsollen, når du muterer objekter

Mange udviklere bruger ikke en debugger, mens de udvikler sig. I stedet stoler de på deres gamle ven console.log().

Det er vigtigt at bemærke, at konsollen viser objektets værdi, der evalueres på tidspunktet for den første udvidelse i konsollen.

Lad mig først afklare, hvad jeg mener med udvidelse. Når vi er console.loget objekt (som også dækker arrays), kollapses objektets værdi. For eksempel:

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

Browserens konsol vil se sådan ud:

Derefter, når du klikker på trekanten, udvides objektet. På det nøjagtige tidspunkt evalueres og vises objektets værdi.

Lad os dykke mere ind i dette og tjekke et eksempel:

På linje 1 initialiserer vi en ny usersvariabel, som er en række objekter.

På linje 6 skriver vi værdien af usersvariablen til konsollen.

Dernæst gentager vi igennem users, kontrollerer om brugeren er gyldig, og afhængigt af tilbagevenden deaktiverer vi brugeren. Af hensyn til argumentet antager vi, at validateUser()returneringerne falseog koden på linje 10 udføres.

Selvom mapder oprettes et nyt array, ændres userobjektet også ændring af userobjektet i usersarrayet. Det ændres, fordi det har samme reference. (Se denne artikel for at få en bedre forklaring på, hvad der sker).

Spørgsmålet er: hvad vises i konsollen, der kaldes på linje 6?

Når vi åbner dette eksempel i Chrome og Firefox, kollapses objektet. Derefter ved udvidelse ser vi værdierne:

Enabled er indstillet til false, selvom værdien var truepå tidspunktet for output. Årsagen bag dette er, at objektets værdi vurderes første gang, når vi klikker for at udvide objektet (doven læsning).

Bemærk: Chrome viser et info-ikon, der siger: "Værdien nedenfor blev evalueret lige nu."

Lad os nu se på Safari:

Hm, aktiveret er indstillet til sand. Så vi kan se, at der er nogle uoverensstemmelser mellem browsere. Safari forsøger automatisk at udvide objektet. Hvis objektet / arrayet er for stort, kollapser det og opfører sig på samme måde som Chrome og Firefox.

En måde at komme rundt på dette er at bruge JSON.stringify(),f.eks

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

der producerer følgende output til konsollen:

Desværre kan du med denne tilgang ikke udvide / skjule et objekt. Værdien muteres ikke.

Jeg er en stor fan af det funktionelle programmeringsparadigme og uforanderlige variabler. For at ændre objektet opretter du en klon, som derefter ændres. I så fald ville du ikke opleve denne slags "problem". Så vi kunne skrive noget som dette:

I kortfunktion kloner vi nu brugerobjektet, som vi ændrer og returnerer.

Hvis du holder fast i objektmutation, tilføjede Zoran Jambor en anden smart løsning:

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

Så brugernes array er destrueret, og en liste over objekter vises i konsollen:

Men her skal vi også være forsigtige. Hvis objektets værdi er blevet muteret, ændres konsoludgangen ved udvidelse:

Hvis du vil være helt sikker på, at objektet, som blev logget, har den samme værdi som det havde under console.log, skal du lave en dyb klon af det. For eksempel kunne vi bruge følgende hjælperfunktion i stedet for at skrive direkte til konsollen:

På linje 3 opretter vi faktisk en dyb klon af objektet, som giver følgende output:

Nu ændres objektets værdi ikke ved udvidelse.

Hvis du bruger en fejlretning, vil udførelsen af ​​en pause i tilføjelse af et brydepunkt til linje 6 stoppe. Du får vist det aktuelle objekts værdi. Hvis du foretrækker konsollen det meste af tiden, skal du være opmærksom på, at objektet / arrayet evalueres ved den første udvidelse.

Tjek denne fantastiske artikel om, hvordan du bruger din browsers fejlfinding.

Tak fordi du læste. Del det med alle, der måske finder det nyttigt, og skriv feedback. (Dette er min første historie på Medium, og jeg vil gerne fortsætte med at skrive og blive bedre til det).