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