2011-03-07 8 views
18

私は今日、javascriptでいくつかの本当に奇妙な動作に遭遇しました。私はそれが何とか今考え出されたと思うが、私が思っていることが本当に起こっているのか、他の魔法が関わっているのか知りたい。なぜconsole.log()は渡された変数のスナップショットを取得しませんか?

var SomeObject = {}; 

    SomeObject.foo = function(a, b) { 
     var baz = this.bar(a, b); 
     console.log(baz); 
     console.log(baz.left); 
     SomeObject.magicalStuff(baz); 
    }; 

    SomeObject.bar = function(a, b) { 
     return {left: a-b, top: b-a}; 
    }; 

    SomeObject.magicalStuff = function(position) { 
     position.left = 0; 
    }; 

    SomeObject.foo(100, 50); 

The code at jsFiddle

これの出力は(ブラウザによって異なります)のようなものです::だからこれは私のコードである

> Object 
50 

あなたがChromeで( "オブジェクト" を展開すると、 SafariまたはFirefox(Firebug)の入手方法は次のとおりです。

> Object 
    left: 0 
    top: -50 
> Object 
    left: 50 
    top: -50 

は何が起こっていると思うと、そのにconsole.log()実際には「ポスト」あなたは「拡大」のシンボルをクリックすると読みますコンソールへの参照です。しかし、console.log()の目的をデバッグ機器として無効にすることはありませんか? 私は常にconsole.log()に渡すものを「スナップショット」することを期待していました。実際のconsole.log()がconsole.log()の呼び出しの出力を変更した後のステートメントを見るのは本当に驚きです。

他に何か起こっていますか?

編集:ブラウザの開発者がconsole.logを実装するのに妥当な理由があるのだろうか(私はそこにあると思います。そうでなければ、主要なブラウザ間で一貫性がないでしょう)。

+1

https://bugs.webkit.org/show_bug.cgi?id=35801を参照してください。 –

+0

@Roatin Marth:わかります。しかし、なぜ彼らは言う: "我々はオブジェクトをコンソールにダンプするときにオブジェクトを複製することはできません"。私が見ることができない技術的な問題は何ですか? :) – fresskoma

+0

これは、すべてのイベントが単一のオブジェクトであるため、通常は最新のmousemoveイベントを見ているため、イベントをログに記録するときによく見られます。 –

答えて

10

あなたがFirebugで望むものはconsole.dir()です。一般的に

オブジェクトは完璧clone方法は非常に困難であるの実装var a = {}; var b = {a: a}; a.b = b;

のような循環参照含めることができるので、にネストされたプロパティのすべてのレベルを印刷することはできません - 私はそれだけで基本的にしなければならないと思いますがメモリ全体をダンプし、ロギングにはかなりの時間がかかります。 console.log(window)を考えてください...

+0

あなたはそこにポイントを持っています。 SafariやChromeなどのWebkitブラウザに類似したものはありますか? – fresskoma

+0

私はそうは思わない。 [上記のバグレポート](https://bugs.webkit.org/show_bug.cgi?id=35801)にあるように、これは問題ありません。Firefoxの 'console.dir()'が問題をプッシュするだけです次のレベルへ – user123444555621

+0

Chromeで 'console.dir'が動作しないことに注意してください。ここでは、ソリューションの比較 - http://jsfiddle.net/luken/M6295/ - Chromeで実行してみてください。 – Luke

6

この動作も見てきましたが、リファレンスが投稿されているように見えます。これを回避するために、のclone()メソッドをログに記録したいものに使用しました。

+1

+1良い回避策です。しかし、私はまた、なぜコンソールがあるのだろうか。ログはこのように実装されます。 – fresskoma

+1

オーバーヘッドについてのネイサンの答えは、それに関係することがあると思います。 – jimmystormig

9

はい、これは起こっていることです。私はそれがconsole.log()呼び出しのオーバーヘッドを最小限に抑えるために行われたと思います。ログの呼び出しごとにすべてのオブジェクトが深くクローンされていると、制御不能になる可能性があります。

これを回避する必要がある場合は、JSON.stringify()か、オブジェクトをクローン化してconsole.log()に転送してください。

+1

ええ、あなたが正しいと思います。それにもかかわらず、私は、console.log()はデバッグ機能であり、すべてが深いクローンであるべきだと思います。それほど驚くことではありません;) – fresskoma

+0

JSON.stringifyは循環参照を持つため、HTML要素に問題が発生する可能性があります。その場合は、要素のouterHTMLを使用しました。 –

関連する問題