Kumu.jsの罠
とあるHTMLの改善でJavaScriptを追加する機会があったのですが、ArrayListを使った連想配列を使って以下のようなコードを書くと…
var array = new Array(); array['foo'] = 'fooVal'; array['bar'] = 'barVal'; array['baz'] = 'bazVal'; var result = ""; for (var i in array) { result = result.concat(i + ":" + array[i] + ","); } document.write(result);
表示結果がこうなっちゃいます。
include:function(value, list) { if(!list){ list = this; } for(var i = 0; i < list.length; i++){ if(list[i] == value){ return true; } } return false; },filter:function(func, lst){ if(!lst){ lst = this; } var ret = ; for(var i = 0; i < lst.length; i++){ var o = lst[i]; if(func(o)){ ret.push(o); } } return ret; },map:function(func, lst){ if(!lst){ lst = this; } var ret = ; for(var i = 0; i < lst.length; i++){ ret.push( func(lst[i])); } return ret; },foo:fooVal,bar:barVal,baz:bazVal,
なんだ?このメソッド定義のような内容は…JavaScript歴の浅いぼくはあせってググりまくりましたが、上記コードが間違ってるとは思えませんでした。で、同僚に助けを求めたところ、
var array = {};
と、Arrayを使用しないようにすれば、期待通りの結果が得られるようになりました。
foo:fooVal,bar:barVal,baz:bazVal,
ん〜〜、腑に落ちん。
で、夜が明けて朝、色々試しているうちに、これはJavaScriptライブラリが悪さしてるんでは無いかという疑念がわいてきました。ロードするライブラリを変えてみると、まあ、お題のとおりkumu.jsが犯人だったわけです。
ソースを見てみると、
Array.prototype = Kumu.extend(Array.prototype, { map:Kumu.map, filter:Kumu.filter, shift:Kumu.shift, unshift:Kumu.unshift, include:Kumu.include });
Arrayのプロトタイプを上書きしてますよ…。まあ、それはいいのだけど、forで操作するとなぜメソッドまでとれてしまうのか…それってどうなのよと思いつつ仕組みを知らないぼく。
はい。調べますともきっと。