「Collection & Copy - JavaScriptにおける古典的継承 (ベータ)」を読んでいて、おっ、と目に留まったのは、次のコード。
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
注目したのは、Array.prototype.slice.apply(arguments, [1]) の部分です。
arguments (Argumentsオブジェクト) は配列要素にアクセスする [] 演算子が使えるけれども、Arrayではないので、slice メソッドは持っていません。arguments.slice(1) などとすると、"arguments.slice is not a function" とエラーになります。しかし、どうやら slice メソッドは [] 演算子で実装されているようなので、上のように、Array のメソッドである slice を arguments に適用してやれば、望み通りの結果が得られるわけです。
Arguments.prototype.slice = Array.prototype.slice; とだけやってもよさそうなものですが、これだと "Arguments is not defined" というエラーになります。
そこで思い出したのが、DOMのNodeListの場合。
以前の記事で、 Array.prototype に forEach, map, zip, fold などを追加すると便利だというようなことを書きました。Gecko の JavaScript 1.5 では forEach や map などがサポートされているようですし、prototype.js 1.4.0 でも Ruby にならった関数 (each, map, などなど) が追加されています。
document.getElementsByTagName() が返す NodeList の要素にアクセスするときに、こういうメソッドが使えると便利なんですが、NodeList は Array ではないので、Array.prototype にメソッドを追加しただけでは使えません。また、NodeList.prototype.map = Array.prototype.map; というコードも、FireFox では有効でしたが、IEではエラーになりました。
仕方がないのであきらめて [] 演算子を使ったコードを書いていたんですが、最初のような方法をとれば、ちゃんと動くんですね。以下は試してみたコードです。apply でなく call を使えば function (li) { ... } を囲む [] は要らなくなります。
<html>
<head>
<title>test</title>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
if (!Array.prototype.map) {
Array.prototype.map = function(f) {
var ret = new Array();
for (var i = 0; i < this.length; i++) {
ret.push(f(this[i], i, this));
}
return ret;
};
}
window.onload = function () {
$("message").innerHTML +=
Array.prototype.map.apply($("myList").getElementsByTagName("li"),
[function(li) {
return li.firstChild.nodeValue;
}]).join(", ");
};
</script>
</head>
<body>
<div id="message">
</div>
<ul id="myList">
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
</body>
</html>
Posted by Hiroyuki KUROSAKI at 2005年10月13日 09:33
今回は、前回の記事「JavaScriptの演算子」の続きです。
今回はプログラム初心者の方には理解しにくい部分が多く、きっと一度読んだだ...
サイン・インを確認しました、 さん。コメントしてください。 (サイン・アウト)
(いままで、ここでコメントしたとがないときは、コメントを表示する前にこのウェブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)