TinyTableV3 のソート実装における文字列比較の問題点
TinyTableV3 は Google Chrome 7 のソート結果がおかしくなる。( http://goo.gl/rEWH )
2010-11-02 02:45:45(step1) string1.toLowerCase(); string2.toLowerCase(); で両値を小文字に変換
2010-11-02 02:46:12(step2) parseFloat() でNumber型の値に変換し、両値とも NaN でなければ string1, string2 に代入
2010-11-02 02:46:18(step3) Date.parse(); でDate値としてパースし、両値とも NaN でなければ string1, string2 に代入
2010-11-02 02:47:25(step4) string1 と string2 を比較し、string1 > string2 なら「1」を、string1 < string2 なら「-1」を、それ以外(string1 === string2) なら「0」を返す
2010-11-02 02:48:40"一般に、その実装の toString か toUTCString メソッドによって生成されえない文字列を与えられたときの Date.parse に生成される値は、実装依存である。" ( ES3 : http://goo.gl/stGI )
2010-11-02 02:50:37"in general, the value produced by Date.parse is implementation-dependent when given any String value ..." ( ES5: http://goo.gl/G8KO )
2010-11-02 02:53:22ate.prototype.toString, Date.prototype.toUTCString で解釈し得ない値が引数の取られたとき、戻り値は実装依存となる。
2010-11-02 02:54:13Date.parse(1) を評価するとき、IE8, Firefox v3.6.12, Opera v10.62 は NaN を返す。 Google Chrome 7 は数値を返す。
2010-11-02 02:57:46そして、Google Chrome 7 において (Date.parse(1) === Date.parse(-1)) は true となる。
2010-11-02 02:57:57TinyTableV3 は NaN を返す挙動を期待しているが、Date.parse はDateフォーマットではない引数に対してどのような値を返すかは実装依存と ES5 で規定されているので好ましい実装ではないと思う。
2010-11-02 03:00:57修正方法としては string1 及び string2 が Date.parse でパース可能な値かどうか正規表現でチェックする事だと思うけど、Dateの書式がESで規定されていない感じなので良くわからない…。
2010-11-02 03:05:16ただ、"1" と "-1" の比較ぐらいなら簡単にできる。 そもそも、parseFloat でNumber型の値に変換できた時点で Date.parse を実行しなくて良いはずだ。
2010-11-02 03:06:35厳密には Date.parse を実行できるか見るために先に正規表現による判定が先にあるべきな気もするけど、とりあえずは修正できるんじゃないかなと。
2010-11-02 03:09:37実証コードを ideone.com ( http://ideone.com/A4M7k ) にUPした。 ideone.com では rhino を使っており、Date.parse('1') は NaN を返す模様。
2010-11-02 03:22:01ideone.com に適応させるため print() を使っているが、console.log() に一括置換すれば Google Chrome 7 で同現象を再現できる。
2010-11-02 03:22:24