Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Infos im Verborgenen: die Console-API

Debugging

Infos im Verborgenen: die Console-API

Die Zeiten sind lange vorbei, als Webworker mit alert() die Geheimnisse einer Webseite ergründen mussten. Mittlerweile haben alle Browser tolle Developer-Tools, von denen die Konsole ein zunehmend mächtigeres Werkzeug darstellt. Es wird sogar an einem Standard für eine Console-API gearbeitet.

Die Funktion console.log() ist trotz immer ausgefeilteren Entwicklertools nach wie vor eine sehr beliebte Debugging-Methode und dürfte den meisten Entwicklern bekannt sein. Die Console-API bietet aber noch deutlich mehr Methoden, die in bestimmten Szenarien nützliche Werkzeuge darstellen können.

Die Console-API ist kein Bestandteil von JavaScript (bzw. ECMAScript) oder des DOM-Standards selbst und war lange Zeit nur eine individuelle Beigabe zu den Browsern. Mittlerweile ist aber eine Spezifikation unter dem Dach der WHATWG in Arbeit.

Hinweis zu den Beispielen

Die folgenden Code-Beispiele solltet ihr in der Konsole der Devtools eines Browsers eurer Wahl ausführen. Noch besser ist es, unterschiedliche Browser dabei zu benutzen, um die unterschiedliche Implementierungen der Console-API zu entdecken. Sämtliche Code-Beispiele sind auch auf Codepen zu finden. Wichtig: Bitte nicht die Codepen-eigene Console-Ansicht nutzen.

Vier verschiedene Log-Level

Es gibt vier grundlegende Ausgabetypen (Log-Level): log, info, warn und error.

Gewichtung Methoden
log debug(), dir(), dirxml(), group(), groupCollapsed(), log(), trace()
info count(), info(), timeEnd()
warn warn()
error assert(), error()
keine Gewichtung, da keine Datenausgabe clear(), groupEnd(), profile(), profileEnd(), table(), time(), timeEnd(), timeStamp()

Quelle: console.spec.whatwg.org/#loglevel-severity

In den Developer Tools aller bekannten Browser kann gezielt nach diesen Typen gefiltert werden. Eine Besonderheit des error-Typs ist, dass zusätzlich zu der eigentlichen Nachricht auch noch der Stacktrace des Fehlers ausgegeben wird.

Code-Beispiel
  1. console.log('console.log()')
  2. console.info('console.info()')
  3. console.warn('console.warn()')
  4. console.error('console.error()')

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja (log und info werden gleich dargestellt)
Apple Safari Ja
Microsoft Internet Explorer 11 Ja
Microsoft Edge 17 Ja
Node.js v10 Ja (keine optische Hervorhebung)

Beliebig viele Argumente ausgeben

Wenn ihr zwei Objekte zusammenfasst und diese ausgebt, ist das Ergebnis ein wenig hilfreiches „[object Object][object Object]“. Glücklicherweise akzeptieren die meisten Console-Methoden beliebig viele Argumente (Variadische Funktion). Der Browser stellt dann jedes Argument in der bestmöglichen Formatierung dar, sodass auch Objekte oder Arrays sinnvoll ausgegeben werden.

Code-Beispiel
  1. var someBoolean = true
  2. var someInteger = 42
  3. var someFloat = 3.1415
  4. var someObject = {
  5.   foo: 'bar',
  6.   nestedProperty: {
  7.     foo: 'baz',
  8.   },
  9. }
  10. var someString = 'It just works'
  11.  
  12. console.log(someBoolean, someInteger,
  13.   someFloat, someObject, someString)

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja (entsprechend der Spezifikation bei console.dir() nicht möglich)
Apple Safari Ja
Microsoft Internet Explorer 11 Ja
Microsoft Edge 17 Ja
Node.js v10 Ja

Gruppierte Ausgaben

Ausgaben können gruppiert werden mit console.group() bzw. console.groupCollapsed() (Gruppe nicht automatisch ausklappen) und console.groupEnd(). Es ist sogar möglich, Gruppen zu verschachteln.

Code-Beispiel
  1. console.log('console.group() creates a group:')
  2. console.group() // No label
  3.   console.log('It can have a label but doesn\'t have to')
  4.  
  5.   console.group('group with a label')
  6.     console.log('Groups can be nested')
  7.   console.groupEnd()
  8.  
  9.   console.log('console.groupEnd() ends a group')
  10.  
  11.  
  12.   console.groupCollapsed('There are collapsed groups, too!')
  13.     console.log('They are collapsed unlike groups
  14.      created with console.group()')
  15.   console.groupEnd()
  16. console.group()
  17.  
  18. console.log('Collapsed groups aren\'t supported
  19.  in all Developer Tools implementations')

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 console.groupCollapsed() in einer anderen Gruppe wird nicht unterstützt
Microsoft Edge 17 Ja
Node.js v10 Ja (Gruppe kann nicht geöffnet/geschlossen werden, console.groupCollapsed() wird identisch zu console.group() dargestellt)

XML-/Objekt-Ausgabe erzwingen

Die Browser verwenden automatisch für den jeweiligen Ausgabetyp die passende Darstellung. Ist dennoch eine andere gewünscht, könnt ihr dies mit den Methoden console.dirxml() (Darstellung als XML-Struktur) oder console.dir() (Darstellung als Objekt) erzwingen. Insbesondere bei DOM-Knoten kann das nützlich sein, um die XML-Darstellung bzw. die Objekt-Notation in der Ausgabe zu sehen.

Code-Beispiel
  1. const domNode = document.body
  2. const testObject = {
  3.   key: 'value'
  4. }
  5.  
  6. console.group('DOM node')
  7.   console.dir(domNode)
  8.   console.dirxml(domNode)
  9.   console.log(domNode)
  10. console.groupEnd('DOM node')
  11.  
  12. console.group('(JSON) object')
  13.   console.dir(testObject)
  14.   console.dirxml(testObject)
  15.   console.log(testObject)
  16. console.groupEnd('(JSON) object')

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja (Firefox wählt Art der Ausgabe selbstständig)
Google Chrome Ja (entsprechend der Spezifikation bei console.dir() nicht möglich)
Apple Safari Ja
Microsoft Internet Explorer 11 Ja (kommt im Beispiel allerdings mit Gruppierung durcheinander)
Microsoft Edge 17 Ja
Node.js v10 Ja

Tabellen ausgeben

In manchen Fällen ist eine baumartige Darstellung nicht sehr hilfreich. Wollt ihr z.B. überprüfen, ob in einem Array von Objekten eine bestimmte Eigenschaft gesetzt ist, kommt ihr mit einer tabellarischen Darstellung leichter ans Ziel. Die Methode console.table() erwartet als ersten Parameter ein Array mit den Daten, die angezeigt werden sollen. Mit dem optionalen zweiten Parameter lässt sich definieren, welche Spalten angezeigt werden sollen. Ihr übergebt dafür ein Array von Property-Strings.

Code-Beispiel
  1. const someTabularData = [
  2.   {
  3.     "id": 1,
  4.     "content": "Hello World"
  5.   },
  6.   {
  7.     "id": 2,
  8.     "content": "I might be some object
  9.      representing an article"
  10.   },
  11.   {
  12.     "id": 3,
  13.     "content": "... consisting of only a few
  14.      characters and still proud of it... :-D"
  15.   },
  16. ]
  17.  
  18. class Article {
  19.   constructor(id, content) {
  20.     this.id = id
  21.     this.content = content
  22.   }
  23. }
  24.  
  25. var article1 = new Article(4,
  26.   'Only unimportant articles have to live
  27.  alongside others in an array }:-)')
  28. var article2 = new Article(5,
  29.   'Both can be displayed in a tabular view')
  30. var article3 = new Article(6,
  31.   'Even though the exact algorithm is still
  32.  not defined (see console.spec.whatwg.org/#table)')
  33.  
  34. console.table(someTabularData)
  35. // Works with arrays (even with arrays of arrays)
  36. console.table([article1, article2, article3], ['content'])
  37. // Works with objects, the 2nd parameter is optional
  38. // and allows to indicate which columns should be shown

Das Code-Beispiel findest Du auch auf Codepen.

Tabellarische Darstellung der Daten in Firefox
Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Nein (Methode nicht implementiert)
Microsoft Edge 17 Ja
Node.js v10 Ja

String-Ersetzungen

Der Console-API-Standard sieht Platzhalter in Strings vor, die mit verschiedenen Datentypen befüllt werden können. Wer die printf-Funktion in C kennt, dem werden Prinzip und Syntax vertraut vorkommen.

Folgende Ersetzungen sind möglich:

Platzhalter Bedeutung
%s Strings
%d oder %i Ganze Zahlen (Argument wird an parseInt() übergeben)
%f Kommazahlen (Argument wird an parseFloat() übergeben)
%o oder %O Objekte mit „optimal nützlicher Darstellung“ bzw. mit „generischer JavaScript-Objekt-Formatierung“ (in manchen Browsern ein leichter Unterschied in der Darstellung)
%c CSS Styles (siehe ein interessantes Issue auf Github für die unterstützten Styles in Chrome/Webkit)
Facebook beispielsweise nutzt die CSS-Styles im Chrome-Browser, um eine Warnung für unbedarfte Nutzer in der Konsole des Browsers anzuzeigen.
Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 %o, %O und %c werden nicht unterstützt
Microsoft Edge 17 %O und %c werden nicht unterstützt
Node.js v10 %c wird nicht unterstützt
Code-Beispiel
  1. console.log('Placeholders can be used in console outputs.
  2.  The formatting algorithm goes from %s to %s and applies
  3.  all provided arguments', 'left', 'right')
  4. console.log(`There are multiple placeholders:
  5. - Strings (%s)
  6. - Integers (%i or %d)
  7. - Floats (%f)
  8. - Objects (%o (implementation-specific "optimally useful
  9.  formatting") or %O (generic JavaScript object formatting))
  10. - CSS styles (%c)`)
  11.  
  12. console.log('Numbers can be formatted as integers
  13.  (e.g. %i which uses parseInt()) or floats
  14.  (e.g. %f which uses parseFloat())', 123.45, 123.45)
  15.  
  16. console.log('Objects can be outputted in 2 modes:
  17.  %o (optimally useful formatting) or %O (generic
  18.  JavaScript object formatting)', {test: 123}, {test: 456})
  19.  
  20. console.log('Certain CSS text styles can be applied
  21.  to outputs: %cEverything which follows is formatted
  22.  - %cuntil the next placeholder', 'background: #333;
  23.  color: #ff0', 'font-size: large; color: #00f')

Das Code-Beispiel findest Du auch auf Codepen.

Profiling

Eine einfache Methode zur Zeitmessung bieten console.time() und console.timeEnd(). Gibt man beiden Methoden das gleiche Label als Argument, ermittelt der Browser die Dauer zwischen den beiden Methodenaufrufen und gibt diese aus.

Nicht Teil des Console-Standards sind die Methoden console.profile() mit dem Gegenstück console.profileEnd() zum Starten/Stoppen des CPU-Profilings und console.timestamp() zum Hinzufügen eines Timestamps zur Timeline in den DevTools.

Code-Beispiel
  1. const randomDelay = Math.floor((Math.random() * 1000) + 1)
  2. // Number between 1 and 1000 (both inclusive)
  3.  
  4. console.time('Delay was')
  5. console.time('Async timer (should execute immediately)')
  6.  
  7. window.setTimeout(() => {
  8.   console.timeEnd('Delay was')
  9.   // Should match label of `console.time()`
  10. }, randomDelay)
  11.  
  12. console.timeEnd('Async timer (should execute immediately)')
  13. // Hello asynchronous JavaScript!

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Ja
Microsoft Edge 17 Ja
Node.js v10 Ja

Methoden-Aufrufe analysieren

Die Funktion console.count() kann sehr nützlich sein um festzustellen, wie oft eine bestimmte Methode aufgerufen wurde. Man übergibt ein Label und der Browser gibt aus, wie oft die entsprechende Methode aufgerufen wurde.

Code-Beispiel
  1. const randomNumberRepetitions =
  2.   Math.floor((Math.random() * 10) + 2)
  3. // Number between 2 and 10 (both inclusive)
  4.  
  5. for (let i = 1; i < randomNumberRepetitions; i++) {
  6.   console.count('Number of calls so far')
  7. }

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Ja (Zähler wird nur nach manuellem Aktualisieren der Webseite zurückgesetzt)
Microsoft Edge 17 Ja (Zähler wird nur nach manuellem Aktualisieren der Webseite zurückgesetzt)
Node.js v10 Ja

Dagegen zeigt console.trace() den Stacktrace an, der zu dem Aufruf der Methode geführt hat, ähnlich wie man das beispielsweise von nicht gefangenen Fehlern kennt.

Code-Beispiel
  1. function firstFunction() {
  2.   middleFunction()
  3. }
  4.  
  5. function middleFunction() {
  6.   lastFunction()
  7. }
  8.  
  9. function lastFunction() {
  10.   console.trace('Label for the callstack')
  11. }
  12.  
  13. firstFunction() // Start call

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Ja
Microsoft Edge 17 Ja
Node.js v10 Ja (zeigt zusätzlich noch Node-Stacktrace an)

Sonstige Methoden

Mit console.clear() kann die Konsole geleert werden.

Code-Beispiel
  1. console.group('group 1')
  2.   console.log('inside group 1')
  3.  
  4.   console.group('group 2')
  5.     console.log('entire console will be cleared
  6.      after 5 seconds')
  7.     setTimeout(clearConsole, 5 * 1000)
  8.   console.groupEnd()
  9. console.groupEnd()
  10.  
  11. function clearConsole() {
  12.   console.clear()
  13.   console.log('After clearing the console,
  14.    there are no groups remaining...')
  15. }

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Ja
Microsoft Edge 17 Ja
Node.js v10 Ja

Dabei zeigt console.assert() nur Nachrichten an, wenn der erste Parameter falsy ist. Anders als das Schlüsselwort assert in Java beispielsweise ist diese Methode nur für die bedingte Ausgabe gedacht und kann nicht zur Steuerung des Programmflusses verwendet werden.

Code-Beispiel
  1. console.assert(true, 'this message will not be outputted')
  2. console.assert(false, 'only this one')
  3. console.log('some message after the failed assertion')

Das Code-Beispiel findest Du auch auf Codepen.

Support in Browsern und Node.js
Browser/Node Support
Mozilla Firefox Ja
Google Chrome Ja
Apple Safari Ja
Microsoft Internet Explorer 11 Methode implementiert, funktioniert aber nicht wie vorgesehen
Microsoft Edge 17 Ja
Node.js v10 Ja

Fazit

Für bestimmte Szenarien kann die Console-API eine nützliche Ergänzung des Debugging-Werkzeugkastens sein, da sich mit der einen oder anderen Methode viel Zeit oder Debugging-Code sparen lässt. Dazu kommt die vollständige Unterstützung in den wichtigsten Browsern. Selbst ältere Browser wie der Internet Explorer 11 unterstützen viele der Methoden.

Kommentare

wortwart
am 05.07.2018 - 10:28

Interessantes Thema, aber ihr solltet die Listings korrigieren - die Strings laufen über Zeilenumbrüche hinweg.

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Webkraut)
am 05.08.2018 - 17:59

Das habe ich absichtlich so angelegt, damit man nicht scrollen muss und die fortlaufenden Zeilen zumindest richtig eingerückt sind. Hat beides seine Vor- und Nachteile.

Permanenter Link

Sören
am 18.07.2018 - 13:16

Super Erläuterung.
Hinweis: Die Codepen-Links von console.trace() und console.count() sind vertauscht !

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Webkraut)
am 05.08.2018 - 18:05

Danke. Ich habe es geändert.

Permanenter Link
Tim Kraut

Tim Kraut (Autor)
am 07.09.2018 - 10:54

Es gab in der Zwischenzeit noch 2 Ergänzungen:
- console.countReset() zum Zurücksetzen von Zählern mit console.count() (siehe https://console.spec.whatwg.org/#countreset )
- console.timeLog() um Zwischenzeiten mit einer Nachricht ausgeben zu können (siehe https://console.spec.whatwg.org/#timelog)

Permanenter Link

Die Kommentare sind geschlossen.