Quantcast
Channel: Webkrauts - für mehr Qualität im Web
Viewing all articles
Browse latest Browse all 243

Infos im Verborgenen: die Console-API

$
0
0
Leicht aufgeklappter Laptop im NeonlichtDebugging

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.

GewichtungMethoden
logdebug(), dir(), dirxml(), group(), groupCollapsed(), log(), trace()
infocount(), info(), timeEnd()
warnwarn()
errorassert(), error()
keine Gewichtung, da keine Datenausgabeclear(), 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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa (log und info werden gleich dargestellt)
Apple SafariJa
Microsoft Internet Explorer 11Ja
Microsoft Edge 17Ja
Node.js v10Ja (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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa (entsprechend der Spezifikation bei console.dir() nicht möglich)
Apple SafariJa
Microsoft Internet Explorer 11Ja
Microsoft Edge 17Ja
Node.js v10Ja

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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11console.groupCollapsed() in einer anderen Gruppe wird nicht unterstützt
Microsoft Edge 17Ja
Node.js v10Ja (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/NodeSupport
Mozilla FirefoxJa (Firefox wählt Art der Ausgabe selbstständig)
Google ChromeJa (entsprechend der Spezifikation bei console.dir() nicht möglich)
Apple SafariJa
Microsoft Internet Explorer 11Ja (kommt im Beispiel allerdings mit Gruppierung durcheinander)
Microsoft Edge 17Ja
Node.js v10Ja

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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Nein (Methode nicht implementiert)
Microsoft Edge 17Ja
Node.js v10Ja

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:

PlatzhalterBedeutung
%sStrings
%d oder %iGanze Zahlen (Argument wird an parseInt() übergeben)
%fKommazahlen (Argument wird an parseFloat() übergeben)
%o oder %OObjekte mit „optimal nützlicher Darstellung“ bzw. mit „generischer JavaScript-Objekt-Formatierung“ (in manchen Browsern ein leichter Unterschied in der Darstellung)
%cCSS 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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Ja
Microsoft Edge 17Ja
Node.js v10Ja

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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Ja (Zähler wird nur nach manuellem Aktualisieren der Webseite zurückgesetzt)
Microsoft Edge 17Ja (Zähler wird nur nach manuellem Aktualisieren der Webseite zurückgesetzt)
Node.js v10Ja

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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Ja
Microsoft Edge 17Ja
Node.js v10Ja (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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Ja
Microsoft Edge 17Ja
Node.js v10Ja

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/NodeSupport
Mozilla FirefoxJa
Google ChromeJa
Apple SafariJa
Microsoft Internet Explorer 11Methode implementiert, funktioniert aber nicht wie vorgesehen
Microsoft Edge 17Ja
Node.js v10Ja

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.

Tim Kraut

Viewing all articles
Browse latest Browse all 243