JavaScript: The Good Parts のメモ

October 28, 2008category: JavaScript 

JavaScript: The Good Parts より、コード断片のメモ。

p.39 Closure

以下のような HTML において、a ~ b をクリックしたときに、0 ~ 3 を出力したい。

<ol>
  <li>a</li>
  <li>b</li>
  <li>c</li>
  <li>d</li>
</ol>

何も考えないで書くとこうなる。nodes には li のコレクションが渡っている。

var addHanlders = function(nodes) {
  for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick = function() {
      console.log(i);
    };
  }
};

どれをクリックしても 4 が表示される。

クロージャを使うと正しく動作する。

var addHanlders = function(nodes) {
  for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick = function(i) {
      return function() {
        console.log(i);
      }
    }(i);
  }
};

p.41 Curry

カリー化について。

Function.prototype.curry = function() {
  var slice = Array.prototype.slice;
  var args = slice.apply(arguments);
  var scope = this;
  return function() {
    return scope.apply(null, args.concat(slice.apply(arguments)));
  };
};

以下の単純な関数をカリー化してみる。

function add(a, b) {
  return a + b;
}

var add1 = add.curry(1);
console.log(add1(6)); //7

p.44 Memoization

メモ化について。理解できていない。

以下は、フィボナッチ数列を出力する関数。

var fibonacci = function(n) {
  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

項数を 10 で実行すると、442 回も実行されて無駄がある。そこでメモ化。

var fibonacci = function() {
  var memo = [0, 1];
  var fib = function(n) {
    times++;
    var result = memo[n];
    if (typeof result !== "number") {
      result = fib(n - 1) + fib(n - 2);
      memo[n] = result;
    }
    return result;
  };
  return fib;
}();

呼び出しが 29 回に減った。

memoizer として共通化するとこうなる。

var memoizer = function(memo, fundamental) {
  var shell = function(n) {
    var result = memo[n];
    if (typeof result !== "number") {
      result = fundamental(shell, n);
      memo[n] = result;
    }
    return result;
  };
  return shell;
};

var fibonacci = memoizer([0, 1], function(shell, n) {
  return shell(n - 1) + shell(n - 2);
});

comments (0)このエントリーを含むはてなブックマークはてなブックマーク - JavaScript: The Good Parts のメモ

comments