任意の引数の束縛 ― 2006年02月21日 03時00分
前回 JavaScript での引数束縛を扱った際には引数リストの先頭からの束縛だったが、ななしさんによる Array#splice
を使った方法を応用すれば任意の引数の束縛も比較的簡単な形で書ける。C++ には bind1st
、bind2nd
というのがあるそうだが、それと同じようなことができるわけだ。
Function.prototype.bindNth = function (/* n, arg, ... */) {
var self = this;
var args = arguments;
args[0]--;
Array.prototype.splice.call(args, 1, 0, 0);
return function () {
Array.prototype.splice.apply(arguments, args);
return self.apply(this, arguments);
};
};
function concat(a, b) {
return "" + a + b;
}
alert( concat.bindNth(1, "a")("b") ); // "ab"
alert( concat.bindNth(2, "a")("b") ); // "ba"
length プロパティのパフォーマンス ― 2006年02月21日 03時01分
「for 文 2.0」(IT戦記) では length プロパティの評価をループの外に出すことにより高速化を図っています。DOM の NodeList オブジェクト (document.getElementsByTagName()
などで取得) や HTMLCollection オブジェクト (document.forms
などで取得) の length プロパティは「生きている」(オブジェクト取得後の操作が反映される) 、すなわち誤解を恐れずいえば評価のたびに数えなおす必要があるので遅いというのも納得ですが、JavaScript のネイティブオブジェクトである配列の length プロパティはどうなのでしょうか。実際に調べてみました。
以下は 10000 個の span 要素に対する NodeList オブジェクトと配列の length プロパティのパフォーマンスを調べた結果です。数値は 5 回テストした平均値で単位はミリ秒、「先に取得」というのは「for 文 2.0」で紹介されていたように length プロパティの評価を 1 回だけにした場合です。テストはいずれも Pentium M 1.3 GHz 、メモリ 256 MB 、Windows XP のマシン上で行いました。
ブラウザ | NodeList | 配列 | 先に取得 |
---|---|---|---|
Firefox 1.0.7 | 144 | 14 | 2 |
Firefox 1.5.0.1 | 144 | 12 | 4 |
IE 6.01 SP2 | 11062 | 14 | 2 |
Opera 7.54u2 | 54911 | 28 | 18 |
Opera 8.51 | 26 | 12 | 4 |
Opera 9 TP2 | 22 | 12 | 6 |
結果を見ればわかるとおり、NodeList と配列では length プロパティの評価に大きなパフォーマンスの差があります。length プロパティの評価を 1 回だけにするというのは NodeList に対しては有効ですが、配列に対してはよほど性能が求められる場合を除けば大きな意味はないのではというのが個人的な見解です。
それにしても Opera 7 は NodeList の length プロパティの評価が非常に遅いのですが Opera 8 以降では非常に速くなっています。何か特殊な最適化でも施してあるのでしょうか。
最近のコメント