2011-09-11 4 views
1

"Doug Crockford:JavaScript:The Good Parts"の次の機能よく働く。Javascript関数の明らかに矛盾する動作

var fibonacci = function() { 
    var memo = [0, 1]; 
    var fib = function (c) { 
    console.debug(memo, c, memo[c]); 
    result = memo[c]; 
    if (typeof result !== 'number'){ 
     result = fib(c - 1) + fib(c - 2); 
     memo[c] = result; 
    } 
    return result; 
    }; 
    return fib; 
}(); 

console.log(fibonacci(3)); 

しかし、のはそれが予想されるものとは反対の、次の結果を示している4

console.debug(memo, c, memo[c]); 

ラインに何が起こるかを詳細に見てみましょう。

memo,  c, memo[c] 
[0, 1, 1, 2] 3 undefined //contradictory behavior because I expect to have memo = [0, 1] 
[0, 1, 1, 2] 2 undefined //contradictory behavior 
[0, 1, 1, 2] 1 1 
[0, 1, 1, 2] 0 0 
[0, 1, 1, 2] 1 1 
2 

いくつかのアイデアがありますか?

答えて

4

Chromeのコンソール出力に問題があります。 Chromeは、何らかの形で配列の内容を反映するように出力を動的に更新するようです。あなたはFirebugの中でそれを実行した場合、出力は次のとおりです。あなたがあなたの頭の中でコードを通過しようとすると、

[0, 1] 3 undefined 
[0, 1] 2 undefined 
[0, 1] 1 1 
[0, 1] 0 0 
[0, 1, 1] 1 1 
2 

また、それは理にかなって:console.debugfibの最初の文です。最初にfibが呼び出されると、memo[0, 1]であり、配列に何も変更されていないためです。 c3なので、undefinedとなります。したがって、最初の呼び出しでは、memoはコンソールの内容に関係なく[0, 1, 1, 2]になることはできません。

一部のJavaScriptコンソールseem to show such a behaviour(ある意味で)配列やオブジェクトへの参照を記録するとき。このような場合は、ブレークポイントを設定してコードを段階的に進める方がよい場合があります。

更新: Firebugはこの問題を(もし存在すれば)修正したようですが、まだFirebugのライトに存在するようです。

+1

+1 Chromeのオブジェクトを確実にログする唯一の方法は、それらのクローンをログに記録することです。 – pimvdb

関連する問題