15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ウェブクルーAdvent Calendar 2020

Day 3

いまこそ知ってほしい!JavaScriptのconsoleの魅力 2020

Last updated at Posted at 2020-12-02

こんにちは!
ウェブクルー Advent Calendar 2020 の3日目の記事です。
昨日は @kouchanne さんの「Anyダメ絶対! axios編」でした!
TypeScriptでAPIからのresponseデータにも型をセットしたいときに参考にしたいですね。

アドベントカレンダーのお祭り気分を楽しみながら書いていきます!

JavaScriptのconsoleオブジェクトのメソッド

普段使うわりに意外と検索する対象に入らないのではないでしょうか?
知ってみたら、面白いところも便利なところもあるなぁーって感じました。
いろいろ試したことを書いていきます。

JavaScriptのconsole.log()でフォーマット

CSSのフォーマット

ログを出力するのに使うconsole.log()の出力をCSSでフォーマットできるようです。
強調したいログに適用できて便利ですね。

試してみましょう。

const criminal = "御主人"
console.log(`犯人は・・・%c${criminal} %c、あなたです!!!`, "color: red;", "");

console_log_color.gif
第一引数でCSSを適用したい文字の前に%cディレクティブをつけて、
第二引数以降で宣言したCSSを適用させることができましたね。

console.log()は画像も出せる(Chromiumのブラウザのみ)

CSSで画像設定してもコンソールに出力できるようで、Chromeでちょっと試してみました。

console.log("%cHAPPY HOLIDAYS!%c ",
  'color: #FFFFFF; font-size:64px; font-family:"Georgia"; background: -webkit-linear-gradient(0deg, #00BB00, #FFA500, #FF0000); padding: 8px;',
  'background: url(https://1.bp.blogspot.com/-xRE8fggFEAs/X8BV4cGFpYI/AAAAAAABcgE/sgoe7drgu0kgTkUweELLBeGZK0tT7osKgCNcBGAsYHQ/s1103/christmas_mask_santa_tonakai.png); background-size: 100% 100%; padding: 256px 256px');

chrome_holidays.gif
画像も出せましたね!

画像は以下の「いらすとや」さんのものを使っています。
マスクを付けたサンタとトナカイのイラスト(クリスマス) | かわいいフリー素材集 いらすとや

console.log()のCSSのブラウザでの違い

console.log()のCSSですが、ブラウザによって挙動が違いました。
上記のはAppleのサイトっぽく、文字をくりぬいた形にしたかったのですが、
Chromeだと-webkit-background-clip: text;を適用できなかったですね。

cssに-webkit-background-clip使ったconsole.log()
console.log("%cHAPPY HOLIDAYS!",
  'color: #FFFFFF; font-size:64px; font-family:"Georgia"; background: -webkit-linear-gradient(0deg, #00BB00, #FFA500, #FF0000); -webkit-background-clip: text; color: transparent; padding: 8px;');

chrome_clipできない.gif

Firefoxだと可能でした!
firefox_holidays.gif

逆に、Firefoxだと画像が出せなかったです。
なのでサンタさんの画像を出力するところではChromeで実行したGIF画像を貼りました。

CSSは以下を参考:
CSS3でテキストにグラデーションをかける方法
[CSS]background-clipで文字の形に背景を切り取る
background-clip - CSS: カスケーディングスタイルシート | MDN

いろいろなフォーマット

他にも以下のようなフォーマットがあります!

置換文字列 変換用途 備考
%s 文字列
%dまたは%i 整数
%f 浮動小数点 ※Chromeだと動作しない
%oまたは%O オブジェクト

これは「console - Web API | MDN」や「Console Standard #formatting-specifiers」に書いてある通りで、
全部を一気にFirefoxで試してみるとこんな感じですね。


console.log("%s, %.3f, %i, %o", "a", 1.1, 10,{id: 1}); 

firefox_float.gif

JavaScriptのconsoleのメソッドをログレベル別で出力

info()、warn()、error()

ログレベルを変えて出力することも出来ます。
Chromeでの実行結果です。


console.log("log()");
console.info("info()");
console.warn("warn()");
console.error("error()");

chrome_info.gif

log()info() 同じじゃん」って感じなんですが、
次はFirefoxでの実行結果です。
Firefox_info.gif
info()の出力にはlog()の出力にはない「ⓘ」が出てきました!
Firefoxでなら差が出るようです。

warn()error()は、コンソール開くとよく見かけるやつですね。

これらのほかにdebug()というメソッドもあって、
ChromeだとログレベルがVerboseで、Firefoxだとログレベルがデバッグです。

assert()

error()を条件によって出しわけたいなって時に役立つと思います。


console.assert(true, "エラーは出ない");
console.assert(false, "エラーが出る!");

assert.gif
assert()だと、error()に出なかった「Assertion failed: 」がエラーメッセージと一緒に出るようですね。

info()、warn()、error()、assert()もフォーマット可能

Firefoxで試してみた実行結果です。
設定できる置換文字列を全部設定してます(CSSはFirefoxっぽく色を変えてみました笑)。


console.info('%c %s, %.3f, %i, %o',
  'color: #FFFFFF; font-size:64px; font-family:"Georgia"; background: -webkit-linear-gradient(0deg, #9758F5, #E9207A, #FF8552); -webkit-background-clip: text; color: transparent; padding: 8px;', 
  'a', 1.1, 10,{id: 1}
);

firefox_css.gif
こんな感じで、置換文字列がすべてフォーマットされたものが出力されました。

log()、info()、warn()、error()、assert()のグループ分け

Console Standard #loglevel-severity」に書いてあるのですが、
一般的なグループ分けは以下ですね。

グループ分け メソッド 説明
log log() 一般的なログ
info info() 参考になるログ
warn warn() ユーザーになにか警告するログ
error error(), assert() ユーザーにエラーを示すログ

console.time()で時間を計測

time()

console.time()でタイマーを開始し、
console.timeLog()で途中経過時間を出力、
console.timeEnd()でタイマー終了とかかった時間を出力できます。

測定するときに使えそうですね。

time()で測定してみる

試すのにちょうどいいの探して、フィボナッチ数列求める再帰処理がちょうどいいかもと思って
以下の中で使われていたのを参考にさせてもらっています。
Haskellをかける少女
Haskellをかけない中年

(「昨日のコード」)


const fibo = n => (n === 0 || n === 1)? n: fibo(n - 1) + fibo(n - 2);

(「今のコード」)


const rec = (f2, f1, n) => {
  if (n === 1) return f1;
  return rec(f1, f2+f1, n-1);
};
const fibo = n => (n < 2)? n: rec(0, 1, n);

ハスケル子「昨日のコードだと42番目のフィボナッチ数を求めたくらいでSafariが悲鳴を上げ始めますけど、」
ハスケル子「今のコードなら、1000番目のフィボナッチ数が」
ハスケル子「1ミリ秒以下で返ってきます」

どのくらい違うのか、time()を使ってちょっと測ってみました!
上記の「昨日のコード」の処理をChromeで計測してみたものです。


const fibo = n => (n === 0 || n === 1)? n: fibo(n - 1) + fibo(n - 2);
console.time("MyTimer");
console.log(fibo(30));
console.timeLog("MyTimer");
console.log(fibo(35));
console.timeLog("MyTimer");
console.log(fibo(40));
console.timeEnd("MyTimer");

console_time1.gif
40くらいまで行くと時間がかかっているのが数字に表れていますね。

次に、上記の「今のコード」の処理をChromeで計測してみたものです。


const rec = (f2, f1, n) => {
  if (n === 1) return f1;
  return rec(f1, f2+f1, n-1);
};
const fibo = n => (n < 2)? n: rec(0, 1, n);
console.time("MyTimer");
console.log(fibo(30));
console.timeLog("MyTimer");
console.log(fibo(35));
console.timeLog("MyTimer");
console.log(fibo(40));
console.timeLog("MyTimer");
console.log(fibo(1000));
console.timeEnd("MyTimer");

console_time2.gif
今のChromeは末尾呼出しの最適化されているようで、
他の処理の後で1000番目まで計算しても余裕で1ミリ秒以下で返ってきてるのがわかりますね。

time()で複数のタイマー

time()は第一引数に文字列や数字やオブジェクトをラベルとして入れて、
複数のタイマーを用意することもできます。

timelog()はフォーマット可能?

通常のconsole.log()のように複数の引数をとることはできます。
第一引数に%cの文字を入れた文字列をラベルとして設定して、Chromeで試してみましょう。


const time1 = {label: "%ctimer_1", color: "font-size: 16px; color: red;"};
const time2 = {label: "%ctimer_2", color: "font-size: 16px; color: blue;"};

console.time(time1.label, time1.color, "1スタート", "出力されないです");
console.timeLog(time1.label, time1.color);

console.time(time2.label, time2.color, "2スタート", "出力されないです");
console.timeLog(time2.label, time2.color);

console.timeLog(time1.label, time1.color);
console.timeEnd(time1.label, time1.color, "1エンド", "出力されないです");

console.timeLog(time2.label, time2.color);
console.timeEnd(time2.label, time2.color,  "2エンド", "出力されないです");

timelog_color.gif
複数のタイマーを設定したときに、CSSを適用させるのというのは使えるかもしれないですね。

ところで、CSSがラベルだけじゃなくて経過時間にも適用されてる感じですね?
経過時間には別のCSSを適用できそうですね。
こちらもChromeで試してみましょう。


const timerLabel = "%ctimer%c";
const color_2e2623 = "font-size:32px; color: #fff; text-shadow: 1px 1px 1px #2e2623, -1px 1px 1px #2e2623, 1px -1px 1px #2e2623, -1px -1px 1px #2e2623, 1px 1px 1px #2e2623, -1px 1px 1px #2e2623, 1px -1px 1px #2e2623, -1px -1px 1px #2e2623; background: #332826; padding: 16px 4px;"
const color_53b793 = "font-size:32px; color: #fff; text-shadow: 1px 1px 1px #53b793, -1px 1px 1px #53b793, 1px -1px 1px #53b793, -1px -1px 1px #53b793, 1px 1px 1px #53b793, -1px 1px 1px #53b793, 1px -1px 1px #53b793, -1px -1px 1px #53b793; background: #47b58e; padding: 16px 4px;"

console.time(timerLabel);
console.timeLog(timerLabel, color_53b793, color_2e2623);
console.timeLog(timerLabel, color_2e2623 + "text-transform: uppercase;", color_53b793);
console.timeLog(timerLabel, color_53b793, color_2e2623 + "text-transform: uppercase;");
console.timeLog(timerLabel, color_2e2623 + "text-transform: uppercase;", color_53b793 + "text-transform: uppercase;");
console.timeEnd(timerLabel);

timelog_color_one.gif

ラベルと別で経過時間にCSSでフォーマットすることができましたね。
ただ、FirefoxだとCSS適用できなかったです。

CSSは以下を参考:
HTMLとCSSで作れる!見出しに使えるおしゃれな文字装飾サンプル | CJコラム

console.trace()で呼び出し元を追う

trace()

console.trace()を呼び出した場所に至るまでの呼び出し経路を出力してくれるらしいので、
試してみます。

const a = (s) =>  b(s);
const b = (s) =>  c(s);
const c = (s) =>  console.trace(s);
a("trace()");

chrome_trace_.gif

呼び出し元を追えているのがわかりますね!

trace()はフォーマット可能(Chromium)

trace()のログ、もうちょっと賑やかにしてみたくなりませんか?
Chromeでフォーマットできるか試してみました!


const a = (s) => {
  console.trace(`%c a: %s`, 
   "color: red; font-size: 30px;  background: linear-gradient(transparent 60%, #ffff66 0%); ", s);
  b(s);
};
const b = (s) => {
  console.trace(`%c b: %s`, 
   "color: blue; font-size: 30px;  background: linear-gradient(transparent 60%, #ffff66 0%); ", s);
  c(s);
};
const c = (s) => {
  console.trace(`%c c: %s`,
   "color: green; font-size: 30px;  background: linear-gradient(transparent 60%, #ffff66 0%); ", s);
};
a("trace()");

chrome_trace_color.gif
フォーマットできましたね。
ただ、Firefoxだとフォーマットできないです。残念です!

CSSは以下を参考:
CSSでおしゃれな装飾!コピペで見出しをデザインしよう! | みゆ何でもブログ

counsole.count()でカウント

count()

呼び出された回数を出力してくれるようです。
第一引数に文字列や数値、オブジェクトなどラベルを渡して複数管理でき、
不必要に複数回呼ばれてそうな処理がありそうなときとか確認するのに便利かなと思います。


console.count("a");
console.count("b");
console.count("a");

count.gif

count()だとフォーマットはできませんでした

count()は第一引数しか見ていないようで複数の引数を渡しても意味ないです、
フォーマットはできません。

countReset()でカウンターリセット

countReset()でカウンターをリセットできます。これはブラウザですこし違いがありました。
Chromeの実行してみた結果です。


console.count("a");
console.count("a", "b");
console.count("a", "b", "c");

console.log("リセット!");
console.countReset("a");

console.count("a");

chrome_countreset.gif

Firefoxでも実行してみたものです。
firefox_count.gif
countReset()のときに0を出力してくれてて、Firefoxのほうがちょっと親切です笑

console.group()でコンソールのログに階層をつける

複雑な時のログに使えるかもしれないです。

group()、groupCollapsed()

group() 以降の出力を別レベルにインデントして、インライングループを作ってくれるメソッドです。


console.group("1st");
console.group("2nd");
console.group("3rd");

group.gif
group()で出力される文字はすこし大きめに表示されるみたいですね。
わかりやすいですね。

groupCollapsedは最初から折りたたまれた状態で出力します。


console.groupCollapsed("1st");
console.groupCollapsed("2nd");
console.groupCollapsed("3rd");

groupCollapsed.gif

group()の引数

group()groupCollapsed() は引数にとる文字列はログとして出力するために使うようで、
引数の文字が同じでも変えても特に結果に影響はありませんでした。
引数を複数指定することも出来ます。

group()はフォーマット可能

引数がログに出力するために使われ、複数指定可能なところ、
ちょっと気になりませんか?
group()もフォーマットできるかなと試してみました。


for(let n = 1; n < 10; n++){ 
    console.group(`%c Group:%s `, 
    `font-size: ${n*10}px; font-style: italic; letter-spacing: .1em; color: white; text-shadow: -4px 3px 0 #fa4141, -8px 6px 0 black;background:#fa4141; padding: ${n}px;`,n);
}

group_9.gif
やったね!

groupEnd()

groupEnd()1回あたり1階層上に戻れます。
group()と組み合わせて試してみました。


for(let n = 1; n < 7; n++){ 
    console.group(`%c Group:%s `, 
    `font-size: ${n*10}px; font-style: italic; letter-spacing: .1em; color: white; text-shadow: -4px 3px 0 #fa4141, -8px 6px 0 black;background:#fa4141; padding: ${n}px;`,(n + 9).toString(36).toUpperCase());
}
for(let n = 6; n > 0; n--){ 
    console.groupEnd();
    console.log(`%c Group:%s `, 
    `font-size: ${n*10}px; font-style: italic; letter-spacing: .1em; color: white; text-shadow: -4px 3px 0 #fa4141, -8px 6px 0 black;background:#fa4141; padding: ${n}px;`,(n + 9).toString(36).toUpperCase());
}

group_end.gif

groupEnd()で上の階層に戻れてますね。
ちなみに、これはFirefoxでも同じように動きました!

CSSは以下を参考:
CSS見出しデザイン参考100選!コピペ可!どこよりも詳しく解説! | JAJAAAN

console.table()でデータを表で出力

table()で配列を表に出力

普通の配列で試すとこんな感じですね。
比較のためにlog()table()の2つで出力してみます。


const arr = [1,2,3,4,5];
console.log("log()", arr);
console.table(arr);

table_arr.gif
log()だと配列のオブジェクトが表示されるだけですが、
table()だと表が出力されて並べ替えも出来ます。
表の下には配列のオブジェクトも表示されているので多めに情報をもらえる感じですね。

table()でオブジェクトの配列を表に出力

こちらも、
比較のためにlog()table()の2つで出力してみます!
この Console Standard の「Summary of formatting specifiers」の表をtable()を使って再度表にしてます。


const descriptions = []
descriptions.push({"Specifier":"%s","Purpose":"Element which substitutes is converted to a string","Type Conversion":"%String%(element)"});
descriptions.push({"Specifier":"%d or %i","Purpose":"Element which substitutes is converted to an integer","Type Conversion":"%parseInt%(element, 10)"});
descriptions.push({"Specifier":"%f","Purpose":"Element which substitutes is converted to a float","Type Conversion":"%parseFloat%(element, 10)"});
descriptions.push({"Specifier":"%o","Purpose":"Element is displayed with optimally useful formatting","Type Conversion":"n/a"});
descriptions.push({"Specifier":"%O","Purpose":"Element is displayed with generic JavaScript object formatting","Type Conversion":"n/a"});
descriptions.push({"Specifier":"%c","Purpose":"Applies provided CSS","Type Conversion":"n/a"});
console.log("log()", descriptions);
console.table(descriptions);

table_obj.gif
オブジェクトの配列だと見やすいですね!
使える用途はありそうです。

table()でクラスの配列を表に出力

オブジェクトのKeyが違っていても、
クラスがサブクラスでも、別のクラスでも平気なのか?
平気だろうなと想像できるのですが試してみました。


class Data {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
}
class DummyData {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
}
class SubData extends Data {
  constructor(id, name, property, boss) {
    super(id, name);
    this.property = property;
    this.boss = boss;
  }
}
const data      = new Data(1, "Data");
const dummyData = new DummyData(2, "DummyData");
const subData   = new SubData(3,"SubData", 5000, data);
console.log("log()", [data, dummyData, subData]);
console.table([data, dummyData, subData]);
console.table([data, dummyData, subData],["id", "name"]);

table_class.gif

見ればわかるように、
オブジェクトのkeyと階層が一致していれば同じ列に入れてくれるみたいです。
subdataのbossのDataは文字列でないのでクラス名が出力されているようですね。

またtable()の第一引数のオブジェクトのkeyを
第二引数で配列で指定すれば表に出力する列を設定できるようです。

table()で文字列を表に出力は出来ません

表になりません。
log()で出力したようになります。

table()はフォーマットできるかな?

log()のようになるということは文字列をフォーマットできる?
Chromeで試してみました。


console.table(`%cDOLCE%c&%cGABBANA`,
"font-size: 64px; font-family:Roboto,Helvetica Neue,sans-serif;",
"font-size: 32px; font-family:Roboto,Helvetica Neue,sans-serif; padding: 4px;",
"font-size: 64px; font-family:Roboto,Helvetica Neue,sans-serif;");

table_css.gif

CSS行けましたね。
ただ、table()の出力する文字列にCSSを適用させられても、表にCSSを適用させることはできなかったです笑

ちなみに、Firefoxはフォーマットができなくて文字が出力されるだけでした。
Chromiumのブラウザであればフォーマットが可能です。

最後に

楽しんで書いたのですが、
読んで楽しんでいもらえたり、役立つ情報がみつかったなら嬉しいです。
全部紹介したわけじゃないので、参考のページも見てもらえたらより情報が手に入ると思います。

もうすぐ年末ですね。
紅白歌合戦でどうなるのかなって気になってるアーティストさんがいるのでちょっと楽しみです。

明日は@shintaro_ike さんになります。
よろしくお願いします!

ウェブクルーでは一緒に働いてくれる方を絶賛募集中です!
興味のある方はぜひお問い合わせください。
開発エンジニア | 株式会社ウェブクルー

参考

動作環境

PC : Windows 10 Pro (64 ビット)
Chormeバージョン: 86.0.4240.198(Official Build) (64 ビット)
Edgeバージョン: 87.0.664.47 (公式ビルド) (64 ビット)
Firefox : 83.0 (64 ビット)

参考情報

console - Web API | MDN
https://developer.mozilla.org/ja/docs/Web/API/console
Console Standard
https://console.spec.whatwg.org/

[JavaScript]使い分けるだけで今すぐデバッグ効率を上げる、consoleオブジェクトの関数
https://qiita.com/kashira2339/items/874f95aaaa59f4a17d3d
console.logまとめ 2016年夏
https://qiita.com/ykyk1218/items/0f5858d077d43a49cfe2
Node.js v10.0.0でconsole.table()追加&console.log()アップデートに感動したので早速試してみる
https://qiita.com/n0bisuke/items/60e52cde73343bbe7703
console.log()系メソッドまとめ
https://qiita.com/mooriii/items/afad70b19f8150f4f1b1
便利なconsole.xxx
https://qiita.com/ryo2132/items/64c616a4cf0ae8770a9f
【2019年4月版】JavaScriptのconsoleがすごいことになってた。
https://qiita.com/koinori/items/83f119cb2d82c0ca2c1e
JavaScriptでの賢いconsole.log( )の使い方 & その他便利なconsole.xxx( )使い方まとめ (dir・table・warn・groupとか)
https://qiita.com/mtoyopet/items/7274761af5424cee342a
【consoleオブジェクト完全版】ログ出力を極める!
https://qiita.com/sa9ra4ma/items/bc6c12044582126c1be9

マスクを付けたサンタとトナカイのイラスト(クリスマス) | かわいいフリー素材集 いらすとや
https://www.irasutoya.com/2020/11/blog-post_552.html

CSS3でテキストにグラデーションをかける方法
https://marie-web.design/blog/text-gradation/
[CSS]background-clipで文字の形に背景を切り取る
https://qiita.com/teinen_qiita/items/9c23ef3befcb1119bce2
background-clip - CSS: カスケーディングスタイルシート | MDN
https://developer.mozilla.org/ja/docs/Web/CSS/background-clip
CSSでおしゃれな装飾!コピペで見出しをデザインしよう! | みゆ何でもブログ
https://miyu-info.com/midashi/
HTMLとCSSで作れる!見出しに使えるおしゃれな文字装飾サンプル | CJコラム
https://citrusjapan.co.jp/column/cj-column/w006_201803.html
CSS見出しデザイン参考100選!コピペ可!どこよりも詳しく解説! | JAJAAAN
https://jajaaan.co.jp/css/css-headline/
font-familyで指定できるフォント名一覧
https://w3g.jp/sample/css/font-family

Haskellをかける少女
https://qiita.com/Yametaro/items/11dcd3ec26027ff30214
Haskellをかけない中年
https://qiita.com/Yametaro/items/e163affa4b2db48f9957

Food & Beverage by Dolce & Gabbana | Italian specialties | Dolce & Gabbana | Dolce & Gabbana
https://world.dolcegabbana.com/food-beverage/

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?