8 日目の記事です。

みんな大好き console.log() ちゃんですが、%d などの代用文字列を用いて数値を正数化したり値を文字列化したりできます。ログ出力時の文章にこだわりたいときにきっと便利です。

Node.js でも使えます。

使わないでやる例

const input = 123.45;
messageRecord = {
  body: 'Hello World!',
  toString() {
    return this.body;
  },
};

console.log(`入力値 ${parseInt(input)} に該当するメッセージ:${messageRecord}`);
// => 入力値 123 に該当するメッセージ:Hello World!

使う例

// …省略…

console.log('入力値 %d に該当するメッセージ:%s', input, messageRecord);
// => 入力値 123 に該当するメッセージ:Hello World!

一覧

指示子 意味 相当するもの
%d, %i 整数 parseInt() 123
%f 実数 parseFloat() 3.14
%o オブジェクト(良い感じ) console.log() <body>
%O オブジェクト console.dir() {}
%s 文字列 String() "Hi"

全部試すやつ。

console.log('%%d [%d]', 12.34);
console.log('%%i [%i]', 12.34);
console.log('%%f [%f]', 12.34);
console.log('%%s [%s]', { toString() { return 'sss'; } });
console.log('%%o [%o]', { toJSON(){ return '"JSON"' } });
console.log('%%O [%O]', { toJSON(){ return '"JSON"' } });

他に

インライン CSS で装飾できる %c があります。

console.log('%cRED', 'color:red');

%o vs %O

Chrome と Safari が出し分けに対応しています。Firefox は差がない。

まずは単純なオブジェクトで試してみます。

console.log('o [%o]', { a: 123 });
console.log('O [%O]', { a: 123 });

前者小文字の %o はプロパティなどオブジェクト内容のプレビューも表示される。いずれも開閉した内容は同じ。

小文字 %o の方は通常の console.log() と同様、オブジェクトに合わせてできるだけ見やすいよう整形して表示します。要素の場合は DOM ツリーの抜き出しになります。

大文字 %Oconsole.dir() の出力になるようです。オブジェクトの種類に依らず一般的な JS オブジェクトとして出力します。HTML 要素でもプロパティなどが表示されます。

これ HTML 要素だとわかりやすいです。

const el = document.body;
console.log('%o', el);
console.log('%O', el);

Chrome の結果。前者小文字の %o は DOM ツリーの抜き出しに、後者大文字の %O は単なるオブジェクトとしてプロパティなどを表示。

Safari の結果。Chrome と概ね同様。

Firefox の結果。Chrome、Safari と異なり両方とも DOM ツリーの抜き出しになっている。

Firefox は元々 HTML 要素を console.dire() しても DOM ツリーの抜き出しになるので、そういう意味では %O の挙動の一貫性は保たれていると言えはします。

Node.js

Node.js も %s 等に対応しています。API ドキュメントに記載はなかったんですが、例で %s が利用されているのがあります。

> console.log('%%d [%d]', '12.34');
%d [12.34]
undefined

> console.log('%%i [%i]', '12.34');
%i [12]
undefined

> console.log('%%f [%f]', '12.34');
%f [12.34]
undefined

> console.log('%%s [%s]', { toString() { return 'sss'; } });
%s [sss]
undefined

> console.log('%%o [%o]', { toJSON(){ return '"JSON"' } });
%o [{ toJSON: [Function: toJSON] { [length]: 0, [name]: 'toJSON' } }]
undefined

> console.log('%%O [%O]', { toJSON(){ return '"JSON"' } });
%O [{ toJSON: [Function: toJSON] }]
undefined

“undefined” が毎回出てくるのは console.log() の戻り値だからです。

%d が整数にならないのは仕様なのか不具合なのか。C 言語では整数化されるので違和感がある。

その他

Chrome の変換が微妙

Chrome で "12.34"%i に与えたら “NaN” になってしまった。(他 は “12” になる。) あとオブジェクトの toString() も利かない。

Living standard では %parseInt% とあるので Chrome が誤っている気がする……いや誤りという表現も違うか。ずれてるというか。

装飾は残る

Chrome の場合、オブジェクト出力が終わって最後の “]” まで色が変わりました。

console.log('%cstyled [%d] [%o] ', 'color:tomato', 12.34, {});

Firefox は変わらず。

おしまい

全体的にどの環境も微妙な感じの仕上がりでした。まあそんな真面目に使うこともないだろうしなあ。

あと今回調べて初めて小文字 %o と大文字 %O の違いを知りました。

参考