LEFログ

:smile

console.log でデバッグするときの落とし穴とその対処法

JavaScriptconsole.log() は便利ですが、注意も必要です。

今回は、自分が最近遭遇したコードを元に、具体的な事例を紹介したいと思います。

事例: エスケープ文字 \t に気づかず === で比較

これは実際のコードを単純化したものです。このコードでは、二つの文字列が同じかどうかを比較しています。

if (str1 === str2) {
  console.log("同じ文字列です");
} else {
  console.log("異なる文字列です");
}

str1str2 は外部から渡された string 型の変数です(TypeScriptで開発していたため、型自体は把握していました)。

ログを見ると次のようになっていました。

異なる文字列です

ここで、 str1str2 の中身を確認します。

console.log(str1);
console.log(str2);

出力結果は次のようになります。

Hello  World
Hello World

わずかに間隔の違いはありますが、すぐに気が付かないかもしれません。

実はそれぞれの変数には、次の文字列が代入されていました。

const str1 = "Hello\tWorld";
const str2 = "Hello World";

この場合、str1 にはエスケープ文字 \t が含まれていますが、str2 では半角スペースが使われています。そのため、=== を使った比較では「異なる文字列です」となっていたのです。

このように、出力結果を見比べるだけでは違いがわかりにくい場合があります。

console.log() ではエスケープ文字が表示されないため、どこが異なるのかは一目ではわかりません。

(もし半角スペースが2つだったら、更に分かりづらかったかもしれません……)

事例2:全く見分けがつかないケース

次のように改行文字 \n が末尾にある場合は更に大変です。

const str1 = "Hello World\n";
const str2 = "Hello World";

出力結果は次のようになります。

Hello World
Hello World

そう、全く見分けがつかなくなるのです。

試しにブラウザ上のコンソールで確認しましょう。次の画像のように、出力結果だけでは区別がつかないです。

対処法:console.log()とJSON.stringify()を組み合わせて使う

そこで、console.log()JSON.stringify() を組み合わせて使うことで、エスケープ文字を含む文字列を視覚的に確認できます。

console.log(JSON.stringify(str1));
console.log(JSON.stringify(str2));

出力結果は次のようになります。

"Hello\tWorld"
"Hello World"

JSON.stringify() を使うことで、エスケープ文字も含めて文字列全体が出力されるため、違いを明確に確認することができます。

まとめ

JavaScriptで文字列を出力する際には、エスケープ文字に注意を払うことが重要です。

console.log()JSON.stringify() を組み合わせて使うことで、エスケープ文字を含む文字列を明確に表示できます。

特に文字列を取り扱うときは気をつけることをオススメします。

(もしかしたらもっと良い方法があるかもしれません。気軽にコメントして頂けると嬉しいです!)

補足(ブログを書いた動機)

例えばRubyだと、putsメソッドを使ったときはエスケープ文字が表示されませんが、pメソッドを使うとエスケープ文字が表示されます。

JavaScriptにもpメソッドに相当するようなメソッドがないか調べていますが、今のところ見つけられていません……。