Numberクラスに対する拡張

【抜粋】
Object.extend(Number.prototype, {
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }
});

既存のNumberクラスに対してメソッドを追加しています。以下は同じ意味です。

【例】
var obj = new Object();
obj.toColorPart = function() {(省略)}
obj.succ = function() {(省略)}
obj.times = function() {(省略)}
Object.extend(Number.prototype, obj);

Numberクラスのインスタンス*1で使用できます。

toColorPartメソッド

【抜粋】
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

数値(this)をtoString()*2で16進文字列に変換します。10進で16未満、つまり16進で1桁の場合は'0'を頭に付けて返却します。

主な用途は色の10進表現(rgb(n,n,n))を16進表現(#rrggbb)に変換することのようです。例として、Netscape等ではelement.style.color等で取得できる文字列が10進表現であるため、16進に変換したい場合があります。

【例】
<html>
<head>
<title></title>
<script language="javascript" src="prototype.js" charset="utf-8"></script>
<script language="javascript">
<!--
function init(){
  var color = document.body.style.backgroundColor;
  alert(color); //Netscape等は"rgb(0, 206, 209)"と表示される
  var rgb10 = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/i);
  if(rgb10 != null){
    var rgb16 = "#" + Number(rgb10[1]).toColorPart()
                    + Number(rgb10[2]).toColorPart()
                    + Number(rgb10[3]).toColorPart();
    alert(rgb16); //"#00ced1"と表示される
  }
}
//-->
</script>
</head>
<body style="background-color:#00ced1" onload="init();">
</body>
</html>

簡単に説明すると、"rgb(0, 206, 209)"の数値部分を正規表現で抜き出し、Numberオブジェクトに変換してからtoColorPart()で16進表現にしています。(もっといい例があるかもしれませんが^^;)

succメソッド

【抜粋】
  succ: function() {
    return this + 1;
  },

数値(this)をインクリメントして返却しています。

timesメソッド

【抜粋】
  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }

数値(this)の回数分、引数iteratorの関数を実行するメソッドです。ここでのiterator関数は引数を1つ取ることができ、ここに0〜(数値(this)-1)の値が入ります。

$Rは後述する関数で、これも後述するObjectRangeクラスのオブジェクトを返却します。ObjectRangeオブジェクトは「上限、下限を伴う値の範囲をあらわすもの」です。第一引数が下限、第二引数が上限、第三引数が上限値を範囲に含めるかどうかを指定します。(trueで含めない)

eachメソッドはその引数の関数を、上記の範囲の数値を引数としてそれぞれ実行するものです。

・・・と、簡単に書きましたが、実際にコードを追ってみると結構分かりにくいです。(少なくとも筆者には^^;) 前述「Functionクラスに対する拡張」で書いたクロージャとレキシカルスコープを駆使しています。詳しくは後述「Enumerable オブジェクト」で書きたいと思います。

【例】
var num = 3;
num.times(function (index){alert(index);});
//"0", "1", "2"が順に表示される。

*1:数値。ただし、5.succ();では「.」が小数点と解釈されエラーとなる。0x5.succ();や(5).succ();は可能。

*2:Numberクラスの既存メソッド