2012-01-05 12 views
10

JavaScriptやChromeコンソールの動作に深く混乱しています。誰かが私の理解を助けることができる?変数がまだ割り当てられていないよう - - 代わりに、それは印刷し、私は[]を印刷するCOPIED 1を期待JavaScriptコンソールに変数が割り当てられる前に割り当てられた値が出力されますか?

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array); 
} 

initialiseArray(); 
copyToNewArray(); 

は基本的に私は、次のJavaScriptコードは、任意の関数や他のスコープ内にネストされていません[2, 9, 8, 6, 0, 2, 1] - それが割り当てられた後の値です。

なぜですか?

ちなみに、8行目をinitial_array = copied_arrayに置き換えた場合、RESULTS 1は確かに[]と表示されます。それは.pushを使用すると何か?

+0

興味深い。これは同じ問題に対処しているようですか? [リンク](http://zef.me/2843/javascript-the-scope-pitfall) – j08691

+4

似たような質問:http://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-評価する配列 – diEcho

答えて

8

を印刷する前に、配列をコピーすることができます。行にブレークポイントを置く:

for (var i = 0; i < initial_array.length; i++) { 

とあなたが望む行動が表示されます。

実際にconsole.logを非同期で実行すると、Chromeデバッガが値をすぐに '印刷'するという誤った前提があります。配列は実際に値を表示するときにバックエンドで参照渡しされるので、現在は値を表示しています。

+0

Chromeスクリプトデバッガをお勧めします。私はWebstormデバッガで大した成功を収めずに試していました。 – Osy

+0

良い答え...ロガーロガー:( – Nicole

0
var initial_array = []; 
function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 
function copyToNewArray() { 
    var copied_array = []; 
    console.log("COPIED 1", copied_array); 
    alert(copied_array.length); 
    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 
    console.log("COPIED 2", copied_array); 
} 
initialiseArray(); 
copyToNewArray(); 

alert(copied_array.length);行を追加すると正しい結果が表示されます。

何が起こるかは、ログがJavaScriptの実行と同期していないことです。ログが印刷されると、値はすでに変更されています。

1

これは、Chromeコンソールに配列が表示される方法です。これは参考になります。あなたが正確な結果をしたい場合は、文字列に変換します。

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array.toString()); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array.toString()); 
} 

initialiseArray(); 
copyToNewArray(); 

あなたはかなり簡単にこれをテストすることができます。

var x = []; 
console.log(x), x.push(5), x; // outputs [5] and [5] 
+0

まだ、あなたはそれが適切な時点で配列参照をレンダリング/文字列化/解決すると思うでしょう。そうでなければ 'console.log'配列はほとんど動作しません。 Firefoxはこれにも屈するだろうか、それとももっと知的なのだろうか? –

+0

@LightnessRacesinOrbit:それほど知的ではなく、すべてを文字列に変換するので、うまくいくはずです。 (FireBug、もう一方では...私は確信していません) – Ryan

+0

この場合、参照をあまりにも遅くバインドしておくことは、POLSに明らかに違反するため、「より知的」であることを提案します。 (FWIW、私はFirebugを言うつもりでした) –

1

コンソールは、実際には非同期です。オブジェクトへの参照をログに記録しているので、オブジェクトがログに記録されるまでにはすでに変更されています。

ログに記録する前にアレイをクローンして、ログに記録される前に変更されていないことを確認してください。

3

配列は参照渡しであるため、変更するたびにコンソールに出力される内容が変更されます。これはChromeのコンソールの一部の動作で、一部はJavaScriptです。

console.logの呼び出し時に結果を印刷する場合は、JSON.stringifyを使用して文字列として出力できます。

console.log("COPIED 1", JSON.stringify(copied_array)); 

重要な編集

私がほとんど間違っていたようです。 diEchoが質問のコメントで指摘されているように、similar questionbetter answerです。これは単にクロムのようなものです。

+0

この現象は、FirefoxのWeb開発者コンソール(Firebugではなく、株式ブラウザ1)でも見つかります。だから多分それはクロームの行動だけではありません。 –

0

copied_arrayが参照であり、console.logが非同期に実行されるため、最初のログが出力される前に配列の内容が変更されます。

あなたはクロームスクリプトデバッガであなたの問題をデバッグしてみ

console.log([].concat(copied_array)); 
0

あなたは、このような配列内のオブジェクトを拡大すると、コンソールの機能を維持したい場合は、私がログインしたときに変更されない配列のコピーを作成し.sliceを、使用することをお勧め:

console.log("COPIED 1", copied_array.slice()); 
+0

いいですが、JSON.stringify(copied_array)メソッドはよかったと思います。 –

関連する問題