今日、同僚がいくつかのコードをデバッグするのを手伝っていましたが、Google Chromeのconsole.log()
の奇妙な動作に気づきました:
次のような場合、
ネストされた配列を作成します([[345、 "test"]]など)
console.log()
を使用して、アレイをコンソールに記録します。
内部配列の値の1つを変更すると、console.log()
は、後で配列の値を出力します-notconsole.log()
が実行されました。
JavaScript:
_var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]
var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}
var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]
_
この動作はFirefoxでは発生しません。
また、Chromeデバッガーで彼のコードを1行ずつ実行した場合、console.log()
は正しい値を出力します。
この奇妙な現象の説明はありますか、それともGoogle Chromeの単なるバグですか?
編集:
一貫性のないconsole.log()
の動作を再現するために手順を絞り込みました:
このスクリプトをページに追加した場合:
_var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
greetings.Push('goodbye');
},3000);
_
Chromeconsole window already open)を使用して新しいウィンドウで開き、次にconsole.log()
出力は、コンソールウィンドウを閉じた状態でページをロードした場合とは異なります。 これを示すJSFiddleです 。
最初のケースでは、コンソールウィンドウが既に開いている状態で、console.log()
は配列の現在の値(2つの項目)を出力します。
2番目のケースでは、コンソールウィンドウが最初に閉じられ、ページが読み込まれた後だけに開かれるため、console.log()
は配列の最後の値(つまり、3つのアイテム)。
これはGoogle Chromeのconsole.log()
機能のバグですか?
何度も調べたところ、これはバグとして報告されており、Webkitで修正されていますが、Google Chromeにはまだ組み込まれていないようです。
私が知る限り、問題は最初にここで報告されました: https://bugs.webkit.org/show_bug.cgi?id=35801 :
説明ミッチクレイマーから2010-03-05 11:37:45 PST
1)1つ以上のプロパティを持つオブジェクトリテラルを作成する
2)そのオブジェクトのconsole.logを閉じたままにする(コンソールで展開しないでください)
3)プロパティの1つを新しい値に変更する
このconsole.logを開くと、生成された時点で値が異なっていたとしても、何らかの理由で新しい値が表示されていることがわかります。
あなたがそれを開いた場合、それが明確でなければ、それは正しい値を保持することを指摘しておきます。
Chromium開発者からの応答:
コメント#2 Pavel Feldmanから2010-03-09 06:33:36 PST
これを修正するつもりはないと思います。オブジェクトをコンソールにダンプするときにオブジェクトのクローンを作成することはできません。また、オブジェクトのプロパティの変更をリッスンして、常に実際のものにすることもできません。
ただし、既存の動作が想定されていることを確認する必要があります。
修正wasは2年半後の2012年8月9日にWebkit( http://trac.webkit.org/changeset/125174 )に実装されましたが、まだChrome=)になっていないようです。
現在、オブジェクト(配列)をコンソールにダンプすると、オブジェクトのプロパティがコンソールオブジェクトの展開時に(つまり、遅延して)読み取られます。つまり、変更中に同じオブジェクトをダンプすると、コンソールを使用してデバッグするのが難しくなります。
この変更により、ロギングの時点でオブジェクト/配列の省略プレビューの生成が開始され、この情報がフロントエンドに渡されます。これは、フロントエンドがすでに開かれている場合にのみ発生します。これは、console.log()でのみ機能し、コンソールの実際の対話では機能しません。
このバグ/機能の回避策を見つけました。
console.log(JSON.parse(JSON.stringify(myObject)));
編集:残念ながら、これは関数のような非プリミティブ値に対しては機能しません。ここで別のクローンユーティリティを使用します。
jQueryの例:
console.log($.extend({}, myObject));