« Japanize 拡張機能 0.7.1 リリースのおしらせ | メイン | OSS コンファレンスで講演 »

2006年10月16日

JavaScript で Generic Programming

 再帰呼び出しのスタック間でデータを共有する場合は、以下のように仮引数を使わなければならない。

IT戦記 - Perl で再帰呼出し時のスタック間データ共有

 について、弾さんがクロージャを使って解決する方法を提示されています。それはそれでいいと思うのですが、JavaScript の場合は、もうひとつの書き方があります。Function.prototype.call を使う手です。

function count_tags(node) {
    return (function (node) {
        var kids = node.childNodes;
        for (var i = 0; i < kids.length; i++) {
            var kid = kids[i];
            if (kid.nodeType != 1) continue;
            if (! this[kid.nodeName]) this[kid.nodeName] = 0;
            this[kid.nodeName]++;
            if (kid.hasChildNodes()) arguments.callee.call(this, kid);
        }
        return this;
    }).call({}, node);
}

 JavaScript は、クラスベースのオブジェクト指向言語ではないので、型にとらわれずに this 変数を使うことができます。クラスベースの言語では、同一の作業を行う関数が複数のクラスにおいて再実装されていることがままあります。あるいは、ユーティリティ関数を共有するためだけの継承が行われたりします。しかし、JavaScript のような非クラスベースのオブジェクト指向言語では、その必要はありません。型にしばられない Generic Programming が容易だからです。

 わかっている人には当たり前の話なのかもしれませんが、JavaScript はいじめられっ子のようなので、褒めてあげることにしました。

 上の例における this の使用が適切かどうかは異論のあるところかもしれませんが、少なくとも、ワンライナーにできる、というのは良いことだと思います。

投稿者 kazuho : 2006年10月16日 11:23 このエントリーを含むはてなブックマーク このエントリーを含むはてなブックマーク

トラックバック

このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/832

このリストは、次のエントリーを参照しています: JavaScript で Generic Programming:

» inject、畳み込み from Days on the Moon
IT戦記 - Perl で再帰呼出し時のスタック間データ共有を読んだ時点では気づきもせず、Kazuho@Cybozu Labs: JavaScript で... [続きを読む]

トラックバック時刻: 2006年10月16日 22:13