console.log
は標準化されていないため、動作はかなり定義されておらず、開発者ツールのリリースごとに簡単に変更できます。私の答えがすぐにわかるように、あなたの本は古くなっている可能性があります。
私たちのコードにとって、それconsole.log
は非同期であるかどうかに関係なく、いかなる種類のコールバックなども提供しません。渡した値は、関数を呼び出すときに常に参照および計算されます。
そのとき何が起こるかは本当にわかりません(Firebug、Chrome Devtools、Opera Dragonflyはすべてオープンソースなので、わかりました)。コンソールはログに記録された値をどこかに保存する必要があり、画面に表示されます。レンダリングは確実に非同期で行われ(レート制限の更新に調整されます)、コンソールでログに記録されたオブジェクトとの今後の対話(オブジェクトプロパティの展開など)も同様です。
したがって、コンソールは、ログに記録した可変オブジェクトを複製(シリアル化)するか、それらへの参照を格納します。最初のものは、深い/大きなオブジェクトではうまく機能しません。また、少なくともコンソールでの最初のレンダリングでは、オブジェクトの「現在の」状態、つまりログに記録されたときの状態が表示される可能性がありますObject {}
。この例では、を参照してください。
ただし、オブジェクトを展開してそのプロパティをさらに調べると、コンソールにはオブジェクトとそのプロパティへの参照のみが保存されている可能性があり、オブジェクトを表示すると、現在の(既に変更された)状態が表示されます。をクリックすると+
、bar
例のプロパティが表示されます。
「修正」を説明するためにバグレポートに投稿されたスクリーンショットは次のとおりです。
そのため、一部の値はログに記録されてからかなり経ってから参照される可能性があり、これらの評価はかなり怠惰です(「必要な場合」)。この不一致の最も有名な例は、ChromeのJavaScriptコンソールが配列の評価について怠惰ですか?という質問で処理されます。
回避策は、オブジェクトのシリアル化されたスナップショットを常にログに記録することconsole.log(JSON.stringify(obj))
です。たとえば、を実行します。ただし、これは非円形でかなり小さいオブジェクトに対してのみ機能します。Safariでconsole.logのデフォルトの動作を変更するにはどうすればよいですか?も参照してください。。
より良い解決策は、デバッグにブレークポイントを使用することです。この場合、実行は完全に停止し、各ポイントで現在の値を検査できます。ロギングは、シリアル化可能で不変のデータでのみ使用してください。