Видимо противоречивое поведение функции Javascript

1

Следующая функция, предложенная "Дугом Крокфордом: 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

Некоторые идеи?

Теги:

1 ответ

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.debug - это первый оператор в fib. В первый раз вызывается fib, memo - [0, 1], поскольку никаких изменений в массиве не было. c 3, поэтому вы получаете undefined. Таким образом, при первом вызове memo не может быть [0, 1, 1, 2] независимо от того, что показывает консоль.

Некоторые консоли JavaScript похоже, показывают такое поведение (так или иначе), когда вы регистрируете ссылки на массивы или объекты. В этих случаях часто бывает лучше установить точки останова и пройти шаг за шагом.

Обновление: Кажется, Firebug исправил эту проблему (если она когда-либо существовала), но она все еще существует в свете Firebug.

  • 1
    +1 Единственный способ надежно регистрировать объекты в Chrome - регистрировать их клон ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню