Jeśli w codziennej pracy piszecie coś w JavaScripcie zapewne jednym z podstawowych narzędzi jakich używacie do debuggowania jest właśnie console.log
. Dlaczego więc chcę Was namówić do zmian? O tym już za chwilę.
Powód numer 1 – console.table
Jedną z sytuacji, gdy console.log
bywa przydatne, to gdy w naszej aplikacji przeglądarkowej chcielibyśmy sprawdzić czy zmiany, jakie dokonały się na danym obiekcie są tymi, których oczekiwaliśmy.
Załóżmy zatem, że mamy tablicę obiektów o takiej strukturze:
"company": {
"id": "5edbb1c357b5e6c67e40081f",
"name": "Zepitope",
"address": {
"addressLine": "750 Lefferts Place",
"city": "Marienthal",
"state": "Iowa",
"zipCode": 890
},
"employees": [...]
}
Gdzie employees to kolejna tablica obiektów o takiej z kolei strukturze:
{
"id": "5edbb1c3507336bb56f7aef6",
"firstName": "Barnes",
"lastName": "Odonnell",
"address": {
"addressLine": "867 Arion Place",
"city": "Golconda",
"state": "Puerto Rico",
"zipCode": 925
}
}
Mamy tu zatem kilka poziomów zagnieżdżeń – dość skomplikowaną strukturę. Chcielibyśmy porównać obiekt przed jakimiś zmianami zmianami i po nich. Jeśli wykorzystamy do tego console.log i dodamy do naszego kodu coś takiego:
Tutaj w linijce 4 i 5 mielibyśmy oczywiście jakieś prawdziwe operacje na naszych danych – czy to ich modyfikację czy ponowne pobranie zmienionych danych z serwera. Dla uproszczenia tutaj mamy tylko jedną małą zmianę, która w pełni ilustruje problem.
Jaki będzie efekt wywołania tego kodu?
Na razie jeszcze nie ma w tym nic ciekawego, bo przecież interesuje nas jak zmieniła się wartość lastName dla pierwszego z pracowników w pierwszej firmie. Rozwińmy zatem te wartości przed zmianami i po – abyśmy mogli porównać czy dane faktycznie się zmieniły:
Co tu się stało?
Można by się spodziewać, że przecież skoro w kodzie mamy console.log
wywołany przed i po zmianach, to powinniśmy dostać obraz danych przed i po zmianach właśnie. Jednak tak się nie dzieje. W większości przeglądarek console.log
działa właśnie w taki sposób, że gdziekolwiek byśmy tych danych nie wyświetlili są one na bieżąco aktualizowane i jeśli następują w kodzie jakieś zmiany to nawet wcześniejsze wywołania console.log
będą podawały najnowszą/ostatnią wersję danych.
Co robić?
Pierwsze co chciałabym Wam zaproponować, to moim zdaniem znacznie wygodniejszy sposób wyświetlania danych w konsoli czyli console.table
Co to zmieni w naszym wypadku? Zobaczmy! Zamiast powyższego wywołajmy coś takiego:
Efekt wówczas będzie następujący:
W Chrome nie widać nic ciekawego, ponieważ nie da się zobaczyć właściwości znajdujących się w poszczególnych kolumnach. Natomiast Firefox już bardzo ładnie pokazuje nam różnice pomiędzy obiektem przed i po zmianach. Na dodatek w bardzo czytelny sposób!
Powód numer 2 – console.dir
Jednak nie samymi przeglądarkami człowiek żyje i pewnie zdarza Wam się również pisać JavaScript w Node. Jak wtedy radzić sobie z podobnymi sytuacjami?
Niestety console.table
nie jest tutaj zbytnio przydatne:
Ale console.log
już tak! Zmiana danych wyświetla się prawidłowo.
Dlaczego więc i tutaj chcę Wam zaproponować coś innego? Otóż jak widać o ile z obiektem employees console.log
w Node radzi sobie całkiem dobrze o tyle, gdybyśmy chcieli dowiedzieć się co mieści się w address, to nie będzie możliwe w tak wywołanej komendzie.
Jak sobie z tym poradzić?
Z pomocą przychodzi nam console.dir
. Gdy na obiekcie zdefiniowanym jak powyżej zawołamy następującą komendę:
Otrzymamy taki oto efekt:
Co w tym takiego fajnego zapytacie, bo przecież wygląda tak samo jak w przypadku zwykłego console.log
. To prawda, ale jeśli wywołacie komendę console.dir
z dodatkowymi parametrami:
Wówczas pojawi się również zawartość obiektu address
:
Co się zmieniło?
Różnica polega na tym, że wykorzystaliśmy parametr dodatkowy depth
. Daje on nam możliwość określenia, jak głęboki poziom zagnieżdżeń nas interesuje. Przypisanie parametrowi wartości null
pozwala na wyświetlenie zagnieżdżeń bez żadnych ograniczeń.
Gdybyśmy mu nadali na przykład wartość 1, efekt byłby następujący:
Nie mielibyśmy już dostępu do obiektów w tablicy employees, ponieważ jest to kolejny poziom zagnieżdżenia.
Czy console.dir może nam się przydać również w przeglądarce?
Owszem, console.dir
może ułatwić nam pracę z dokumentem HTML. Kiedy chcemy wyświetlić na przykład obiekt document.body
za pomocą console.log
, to dostaniemy niezbyt wygodny kawałek HTML, natomiast jeśli to samo zrobimy za pomocą console.dir
, dostaniemy reprezentację HTML w postaci obiektu z właściwościami.
Czy to znaczy, że mam już nigdy nie używać console.log?
Oczywiście, że nie. Tak naprawdę console.log
jest bardzo użytecznym narzędziem do debuggowania JavaScriptu przydatnym zarówno w pracy z aplikacjami przeglądarkowymi, jak i konsolowymi/serwerowymi. Świetnie się przy tym sprawdza – zwłaszcza przy mniej skomplikowanych obiektach lub przy wartościach takiego typu jak string
czy number
.
Jednak najważniejsze, to pamiętać, że na tej jednej komendzie świat się nie kończy i obiekt console
ma nam dużo więcej do zaoferowania, niż tylko to narzędzie.
Na koniec dodam jeszcze, że console.log
również pozwoliłoby nam na podobne rzeczy jak console.table
czy console.dir
.
Jeśli uruchomimy kod:
Zatem możemy porównywać obiekty przed i po zmianach również za pomocą console.log
tylko musimy pamiętać o użyciu JSON.stringify
, co jednak wymaga od nas nieco więcej pisania;)
Jak widać, w Node znowu nie widzimy wszystkich zagnieżdżeń, co może nam utrudnić debuggowanie. Wcześniej radziliśmy sobie z tym wywołując:
Tymczasem takie wywołanie jest równoważne z:
Wykorzystujemy tutaj pakiet util
dostepny w Node. Efekt będzie następujący:
Jak widać jest sporo różnych sposobów na debuggowanie JavaScriptu czy to w przeglądarce czy w konsoli. A jakie są Wasze ulubione sposoby?
Dodatki
Testowe dane, jakich użyłam do stworzenia tego przykładu zostały utworzone za pomocą bardzo fajnego narzędzia do generowania danych w formacie JSON: JSON Generator. Pewnie jeszcze napiszę o nim więcej w najbliższym czasie.
Z kolei te testowe dane oraz wszystkie operacje jaki na nich były tutaj pokazane znajdziecie na specjalnie przygotowanym do tego celu CodeSandbox.