コンソール

現行標準 — 最終更新

参加方法:
GitHub whatwg/console (新しい課題, 未解決課題)
Matrixでチャット
コミット履歴:
GitHub whatwg/console/commits
このコミット時点のスナップショット
@consolelog
テスト:
web-platform-tests console/ (進行中の作業)
翻訳 (参考情報):
日本語
简体中文
한국어

概要

この仕様はコンソールデバッグ機能のためのAPIを定義します。

ステータス

この仕様は初期段階の作業であり、より正確かつ互換性のある定義に向けて改良するためのフィードバックを歓迎します。また、これは編集者にとって初めての仕様でもあるため、ご親切かつ建設的なご意見をお願いします。

さらなる議論のため、issue trackerにご参加ください。

1. 名前空間 console

[Exposed=*]
namespace console { // 下記の名前空間オブジェクト要件も参照
  // ロギング
  undefined assert(optional boolean condition = false, any... data);
  undefined clear();
  undefined debug(any... data);
  undefined error(any... data);
  undefined info(any... data);
  undefined log(any... data);
  undefined table(optional any tabularData, optional sequence<DOMString> properties);
  undefined trace(any... data);
  undefined warn(any... data);
  undefined dir(optional any item, optional object? options);
  undefined dirxml(any... data);

  // カウント
  undefined count(optional DOMString label = "default");
  undefined countReset(optional DOMString label = "default");

  // グループ化
  undefined group(any... data);
  undefined groupCollapsed(any... data);
  undefined groupEnd();

  // タイミング
  undefined time(optional DOMString label = "default");
  undefined timeLog(optional DOMString label = "default", any... data);
  undefined timeEnd(optional DOMString label = "default");
};

歴史的な理由により、console は小文字になっています。

console は、開発者コンソールが開かれていない、もしくは存在しない場合でも、スクリプトから常に見えて使用可能であることが重要です。

歴史的なウェブ互換性の理由により、consolenamespace object の[[Prototype]]は、 ObjectCreate(%ObjectPrototype%)で作成された空のオブジェクトでなければならず、 %ObjectPrototype%そのものではありません。

1.1. ロギング関数

1.1.1. assert(condition, ...data)

  1. conditionがtrueの場合、returnする。

  2. messageを、書式指定子を含まない一般的なアサーション失敗(例:"Assertion failed")を示す文字列とする。

  3. dataの場合、appendmessagedataに追加する。

  4. それ以外の場合:

    1. firstdata[0]とする。

    2. first文字列でない場合、prependmessagedataの先頭に追加する。

    3. それ以外の場合:

      1. concatmessage、U+003A(:)、U+0020 SPACE、およびfirstの連結とする。

      2. data[0]にconcatをセットする。

  5. Logger("assert", data)を実行する。

1.1.2. clear()

  1. 適切なgroup stack空にする

  2. 環境で可能ならば、コンソールをクリアする。(不可能な場合は何もしない。)

1.1.3. debug(...data)

  1. Logger("debug", data)を実行する。

1.1.4. error(...data)

  1. Logger("error", data)を実行する。

1.1.5. info(...data)

  1. Logger("info", data)を実行する。

1.1.6. log(...data)

  1. Logger("log", data)を実行する。

1.1.7. table(tabularData, properties)

tabularDataのプロパティの列(もしくはproperties)とtabularDataの行でテーブルを構築し、logLevelを「log」として記録しようと試みる。引数が表形式として解析できない場合は、そのまま記録する。

TODO: ここは良いアルゴリズムが必要。

1.1.8. trace(...data)

  1. trace は、この関数が呼び出された場所からのコールスタックの、実装定義であり、対話型の可能性もある表現であるとする。

  2. 必要に応じて、formattedDataFormatter(data) の結果とし、trace のラベルとして formattedData を組み込む。

  3. Printer("trace", « trace ») を実行する。

スタックトレースに出力される関数の識別子は 実装定義 です。また、new Error().stack で表示される識別子と同じである保証はありません。

1.1.9. warn(...data)

  1. Logger("warn", data)を実行する。

1.1.10. dir(item, options)

  1. objectitem汎用JavaScriptオブジェクト形式 を適用したものとする。

  2. Printer("dir", « object », options)を実行する。

1.1.11. dirxml(...data)

  1. finalListを新しいリスト(初期状態は空)とする。

  2. dataitemについて:

    1. convertedを、可能ならitemのDOMツリー表現とし、できない場合は最適な有用形式itemに適用したものとする。

    2. convertedfinalListに追加する。

  3. Logger("dirxml", finalList)を実行する。

1.2. カウント関数

console 名前空間オブジェクトには、カウントマップが関連付けられている。これは、マップであり、 文字列から 数値への対応付けで、初期状態は空である。

1.2.1. count(label)

  1. mapを関連付けられたカウントマップとする。

  2. map[label]が存在する場合、setmap[label]をmap[label] + 1にする。

  3. そうでない場合、setmap[label]を1にする。

  4. concatlabel、U+003A(:)、U+0020 SPACE、および ToString(map[label])の連結とする。

  5. Logger("count", « concat »)を実行する。

1.2.2. countReset(label)

  1. mapを関連付けられたカウントマップとする。

  2. map[label]が存在する場合、setmap[label]を0にする。

  3. そうでない場合:

    1. messageを、書式指定子を含まない「指定されたラベルに関連付けられたカウントが存在しない」ことを示す一般的な文字列とする。

    2. Logger("countReset", « message »)を実行する。

1.3. グループ化関数

グループは、実装定義であり、インタラクティブである可能性のある、Printerによって生成された出力のビューであり、親よりもインデントが一段階深くなる。各console 名前空間オブジェクトには、グループスタックが関連付けられている。これはスタックであり、初期状態は空。グループスタック内の最後のグループのみがPrinterによって生成された出力を保持する。

1.3.1. group(...data)

  1. groupを新しいグループとする。

  2. data空でない場合、groupLabelFormatter(data)の結果とし、空の場合は実装依存のグループラベルとする。

  3. groupLabelgroupのラベルとして組み込む。

  4. 任意で、環境がインタラクティブグループをサポートする場合は、groupをデフォルトで展開する。

  5. Printer("group", « group »)を実行する。

  6. Pushgroupを適切なグループスタックに追加する。

1.3.2. groupCollapsed(...data)

  1. groupを新しいグループとする。

  2. dataが空でない場合、groupLabelFormatter(data)の結果とし、空の場合は実装依存のグループラベルとする。

  3. groupLabelgroupのラベルとして組み込む。

  4. 任意で、環境がインタラクティブグループをサポートする場合は、groupをデフォルトで折りたたむ。

  5. Printer("groupCollapsed", « group »)を実行する。

  6. Pushgroupを適切なグループスタックに追加する。

1.3.3. groupEnd()

  1. Popグループスタックから最後のグループを取り除く。

1.4. タイミング関数

console 名前空間オブジェクトには、タイマーテーブルが関連付けられている。これはマップであり、 文字列から 時刻への対応付けで、初期状態は空である。

1.4.1. time(label)

  1. 関連付けられたタイマーテーブルlabelキーのエントリが 存在する場合、returnし、必要に応じてlabelのタイマーが既に開始されていることを示す警告をコンソールに表示してもよい。

  2. そうでない場合、setで関連付けられたタイマーテーブルlabelキーの値を現在時刻にする。

1.4.2. timeLog(label, ...data)

  1. timerTableを関連付けられたタイマーテーブルとする。

  2. startTimetimerTable[label]とする。

  3. durationを現在時刻とstartTimeの差分を表す文字列とする。形式は実装定義とする。

    "4650", "4650.69 ms", "5 seconds", "00:05" などが4650.69 msの持続時間を表示する合理的な方法例。

  4. concatlabel、U+003A(:)、U+0020 SPACE、およびdurationの連結とする。

  5. Prependconcatdataの先頭に追加する。

  6. Printer("timeLog", data)を実行する。

timeLog()呼び出し時のdataパラメータは Logger呼び出しに含まれるため、ユーザーがタイマーの途中経過ログに追加データを簡単に渡せます。例:
console.time("MyTimer");
console.timeLog("MyTimer", "アプリケーション起動中…");
// ここで複雑なアプリの初期化コードが走るかも
// ...
console.timeLog("MyTimer", "UIセットアップ完了、APIコール開始");
// ここでfetch()などでアプリにデータ投入
// ...
console.timeEnd("MyTimer");

1.4.3. timeEnd(label)

  1. timerTableを関連付けられたタイマーテーブルとする。

  2. startTimetimerTable[label]とする。

  3. RemovetimerTable[label]を削除する。

  4. durationを現在時刻とstartTimeの差分を表す文字列とする。形式は実装定義とする。

  5. concatlabel、U+003A(:)、U+0020 SPACE、およびdurationの連結とする。

  6. Printer("timeEnd", « concat »)を実行する。

whatwg/console#134参照。 timeEnd()およびtimeLog()が、 指定したlabelが関連付けられたタイマーテーブルに存在しない場合、コンソールに警告を正式に報告する計画。

2. 抽象操作の補助

2.1. Logger(logLevel, args)

logger操作はログレベルとリスト型の追加引数を受け取ります。主な出力は、 実装定義の副作用としてコンソールに結果を表示することです。本仕様では、これを行う際の書式指定子の処理方法について説明します。

  1. argsの場合、returnする。

  2. firstargs[0]とする。

  3. restargs内のfirst以降の全要素とする。

  4. restの場合、 Printer(logLevel, « first »)を実行し、returnする。

  5. それ以外の場合、Printer(logLevel, Formatter(args))を実行する。

  6. return undefined

印字はアルゴリズムからreturnする前に行われることが重要です。多くの開発者コンソールでは、最後に入力した操作の結果が出力されます。そうしたコンソールでconsole.log("hello!")と入力すると、まず"hello!"が表示され、その後console.log呼び出しの戻り値undefinedが表示されます。

Indicating that printing is done before return

2.2. Formatter(args)

formatter操作は、最初の引数を他の引数を使ってフォーマットしようとします。書式指定子が最初の引数に残っていないか、追加引数がなくなるまでフォーマットを試みます。印字に適したリスト型オブジェクトを返します。

  1. argsサイズが1の場合、argsをreturnする。

  2. targetargsの最初の要素とする。

  3. currentargsの2番目の要素とする。

  4. target内の最初の書式指定子specifierを左から右へ探す。

  5. 書式指定子が見つからなければ、argsをreturnする。

  6. それ以外の場合:

    1. specifier%sなら、 Call(%String%, undefined, « current »)の結果をconvertedとする。

    2. specifier%dまたは%iの場合:

      1. currentSymbol型なら、convertedNaNとする。

      2. それ以外なら、 Call(%parseInt%, undefined, « current, 10 »)の結果をconvertedとする。

    3. specifier%fの場合:

      1. currentSymbol型なら、convertedNaNとする。

      2. それ以外なら、 Call(%parseFloat%, undefined, « current »)の結果をconvertedとする。

    4. specifier%oなら、任意でconvertedcurrent最適な有用形式を適用したものとする。

    5. specifier%Oなら、任意でconvertedcurrent汎用JavaScriptオブジェクト形式を適用したものとする。

    6. TODO: %cの処理

    7. 上記のいずれかでconvertedがセットされた場合、target内のspecifierconvertedで置換する。

  7. resulttargetargsの3番目以降の要素を含むリストとする。

  8. Formatter(result)をreturnする。

2.2.1. 書式指定子の概要

上記アルゴリズムで処理される書式指定子の概要(参考)です。

指定子 目的 型変換
%s 置換される要素を文字列に変換 %String%(element)
%d または %i 置換される要素を整数に変換 %parseInt%(element, 10)
%f 置換される要素を浮動小数点数に変換 %parseFloat%(element, 10)
%o 最適な有用形式で要素を表示 n/a
%O 汎用JavaScriptオブジェクト形式で要素を表示 n/a
%c 指定されたCSSを適用 n/a

2.3. Printer(logLevel, args[, options])

printer操作は実装定義です。ログレベル(深刻度)、印字する引数リスト、実装依存の書式オプションオブジェクト(任意)を受け取ります。 argsの要素は以下のいずれかです:

optionsオブジェクトが渡され、undefinedでもnullでもない場合、実装はoptionsを使ってargs内の要素に 実装定義の書式を適用してもよいです。

実装がargsをどう印字するかは実装次第ですが、オブジェクト同士はスペースなどで区切るのが一般的です。

printer操作が呼ばれる時点で全ての書式指定子は処理済みであり、書式指定子に消費される引数はargsに含まれていません。実装の役割は単純にリストを印字することです。Printerの出力は、グループスタックが空でなければ適切なスタックの最後のグループ内にのみ表示され、空の場合はコンソールの他の場所に表示されます。

printer操作呼び出し時にコンソールが開いていない場合、実装は典型的には100件以上の範囲で実装定義の制限までメッセージをバッファし、後で表示するべきです。

2.3.1. logLevelの深刻度の指示

console 関数はPrinter呼び出し時に固有のlogLevel値を使い、印字されたメッセージを関数ごとにカスタマイズできるようにします。ただし、一般的には関数を4つのカテゴリにまとめ、それぞれの出力を同様に扱う慣習があります。表はその一般的なグループ分けのまとめです:

グループ console 関数 説明
log log(), trace(), dir(), dirxml(), group(), groupCollapsed(), debug(), timeLog() 一般的なログ
info count(), info(), timeEnd() 情報的なログ
warn warn(), countReset() ユーザーに何らかの警告を示すログ
error error(), assert() ユーザーにエラーを示すログ

これらのグループ分けは一般的な慣習を文書化するものであり、実装が各関数ごとに特別な挙動を提供することを制約するものではありません。以下はその例です:

ここでは、ある実装がtimeEnd()の出力を青色にし、info()はよりニュートラルな色にした例です。

A demonstration of timeEnd and info formatting differences

count()の呼び出しは常に新しい出力を表示するとは限らず、以前に出力されたカウントを更新することもあります。

A demonstration of count behavior

2.3.2. プリンターのユーザー体験の革新

Printer実装定義なので、実装には多様なUXイノベーションが見られます。次はUX強化の一例(網羅的ではありません):

2.3.3. 一般的なオブジェクト形式

通常、オブジェクトはその文脈に適した形式で印字されます。本節では、オブジェクトが文脈に合わせて最も有用になるようにフォーマットされる一般的な方法を説明します。ここで説明するフォーマットは、 実装定義のオブジェクト表現に適用され、最終的にはPrinterに渡され、実際の副作用(フォーマット)が現れます。

汎用JavaScriptオブジェクト形式のオブジェクトは、汎用JavaScriptオブジェクトの展開可能な表現です。 最適な有用形式のオブジェクトは、 実装定義の、最大限有用かつ情報量の多いインタラクティブな表現です。

2.3.4. Node.jsでのプリンター実装例

Node.jsプラットフォームでprinter操作を最も簡単に実装する方法は、事前にフォーマットした引数をスペース区切りで結合し、stdoutstderrへ出力することです。

[ECMASCRIPT]を用いたNode.jsでの実装例:

const util = require('util');

function print(logLevel, ...args) {
  const message = util.format(...args);

  if (logLevel === 'error') {
    process.stderr.write(message + '\n');
  } else if (logLevel === 'log' || logLevel === 'info' || logLevel === 'warn') {
    process.stdout.write(message + '\n');
  }
}

ここでは多くの処理をutil.format関数が担当します。ネストされたオブジェクトの文字列化や、非文字列引数の可読な文字列への変換(例:undefinedは"undefined"、falseは"false")も行います:

print('log', 'duck', [{foo: 'bar'}]);     // prints: duck [ { foo: 'bar' } ]\n on stdout
print('log', 'duck', false);              // prints: duck false\n on stdout
print('log', 'duck', undefined);          // prints: duck undefined\n on stdout

2.4. コンソールへの警告の報告

コンソールへの警告を報告するには、警告の一般的な説明 descriptionが与えられたとき、実装は次の手順を実行する:

  1. warningdescriptionから導出した実装定義の文字列とする。

  2. Printer("reportWarning", « warning »)を実行する。

謝辞

編集者は、この仕様への貢献に感謝します: Boris Zbarsky、 Brent S.A. Cowgill、 Brian Grinstead、 Corey Farwell、 Ian Kilpatrick、 Jeff Carpenter、 Joseph Pecoraro、 Justin Woo、 Luc Martin、 Noah Bass、 Paul Irish、 Raphaël、 Victor Costan ― みなさん本当にありがとうございました!

本標準は Terin Stock (terin@terinstock.com)、 Robert Kowalski (rok@kowalski.gd)、 Dominic Farolino (domfarolino@gmail.com) によって執筆され、 Domenic Denicola (Google, d@domenic.me) の大きな協力を得ています。

知的財産権

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この文書は クリエイティブ・コモンズ 表示 4.0 国際ライセンス の下で公開されています。その一部がソースコードに組み込まれる場合、ソースコード部分は BSD 3-Clause ライセンスの下で公開されます。

これは現行標準です。特許審査版に関心がある場合は 現行標準 審査ドラフトをご覧ください。

索引

本仕様で定義される用語

参照により定義される用語

参考文献

規範的参考文献

[ECMASCRIPT]
ECMAScript Language Specification。URL: https://tc39.es/ecma262/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola。Infra Standard。現行標準。URL: https://infra.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu。Web IDL Standard。現行標準。URL: https://webidl.spec.whatwg.org/

IDL索引

[Exposed=*]
namespace console { // but see namespace object requirements below
  // Logging
  undefined assert(optional boolean condition = false, any... data);
  undefined clear();
  undefined debug(any... data);
  undefined error(any... data);
  undefined info(any... data);
  undefined log(any... data);
  undefined table(optional any tabularData, optional sequence<DOMString> properties);
  undefined trace(any... data);
  undefined warn(any... data);
  undefined dir(optional any item, optional object? options);
  undefined dirxml(any... data);

  // Counting
  undefined count(optional DOMString label = "default");
  undefined countReset(optional DOMString label = "default");

  // Grouping
  undefined group(any... data);
  undefined groupCollapsed(any... data);
  undefined groupEnd();

  // Timing
  undefined time(optional DOMString label = "default");
  undefined timeLog(optional DOMString label = "default", any... data);
  undefined timeEnd(optional DOMString label = "default");
};

MDN

console/assert

In all current engines.

Firefox28+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js10.0.0+
MDN

console/clear

In all current engines.

Firefox39+Safari7+Chrome25+
Opera12+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12+
Node.js8.3.0+
MDN

console/count

In all current engines.

Firefox30+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js8.3.0+
MDN

console/countReset

In all current engines.

Firefox62+Safari13+Chrome68+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js8.3.0+
MDN

console/debug

In all current engines.

Firefox5+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js8.0.0+
MDN

console/dir

In all current engines.

Firefox8+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/dirxml

In all current engines.

Firefox39+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js9.3.0+
MDN

console/error

In all current engines.

Firefox4+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/group

In all current engines.

Firefox9+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js8.5.0+
MDN

console/groupCollapsed

In all current engines.

Firefox9+Safari5.1+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
Node.js8.5.0+
MDN

console/groupEnd

In all current engines.

Firefox9+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js8.5.0+
MDN

console/info

In all current engines.

Firefox4+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/log

In all current engines.

Firefox4+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/table

In all current engines.

Firefox34+Safari7+Chrome27+
Opera11+Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js10.0.0+
MDN

console/time

In all current engines.

Firefox10+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/timeEnd

In all current engines.

Firefox10+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/timeLog

In all current engines.

Firefox62+Safari13+Chrome71+
Opera60+Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js10.7.0+
MDN

console/trace

In all current engines.

Firefox6+Safari4+Chrome2+
Opera11+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console/warn

In all current engines.

Firefox4+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js0.10.0+
MDN

console

In all current engines.

Firefox4+Safari3+Chrome1+
Opera10.5+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari1+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11+
Node.js0.10.0+