web-dev-qa-db-ja.com

Google Chrome console.log()がオブジェクトや配列と矛盾している

今日、同僚がいくつかのコードをデバッグするのを手伝っていましたが、Google Chromeのconsole.log()の奇妙な動作に気づきました:

次のような場合、

  1. ネストされた配列を作成します([[345、 "test"]]など)

  2. console.log()を使用して、アレイをコンソールに記録します。

  3. 内部配列の値の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"]
_

JSFiddleの例

この動作は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()機能のバグですか?

47
Elliot B.

何度も調べたところ、これはバグとして報告されており、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()でのみ機能し、コンソールの実際の対話では機能しません。

37
Elliot B.

このバグ/機能の回避策を見つけました。

console.log(JSON.parse(JSON.stringify(myObject)));

編集:残念ながら、これは関数のような非プリミティブ値に対しては機能しません。ここで別のクローンユーティリティを使用します。

jQueryの例:

console.log($.extend({}, myObject));
9
cheeZer