DateのgetTime省略と、Math.floorを使わない切捨て計算
ニコニコのJSを眺めていたら、おもしろいコードがあったのでメモする。
var ts = new Date/1000|0;
まず、new Date/1000 。
getTime() を書かなくても、勝手にミリ秒にしてくれるとは知りませんでした。
>>> new Date/1000 1234567890.123 // 上と同じ >>> (new Date).getTime()/1000 1234567890.123
掛け/割り/引き算は数値として扱われるけど、
足し算だと文字列(Date.toString()した値)として扱われるっぽい。
>>> new Date*1 1234567890123 >>> new Date/1 1234567890123 >>> new Date-0 1234567890123 >>> new Date+0 Sat Feb 14 2009 08:31:30 GMT+09000 // (new Date).toString() + 0 と同じ
なので、『(new Date).getTime() なんて長くて書きたくない!』
って人は足し算以外を使うとほんの少しだけスマートに書けるかも。
ただ、無駄な演算をしてるので、その辺も合わせて好みな気がする。
(※) 実行時間は、100万回まわしても誤差の範囲内(数十ms〜数百ms)くらいしか差がなかったです*2。
個人的には、ミリ秒のまま使うならgetTime()と迷うけど、どうせ1000で割ったりするなら、
getTime()無しの方がコードが短くていい感じだと思う。
-
-
- -
-
もう1つ、<少数> | 0 。
何が起きてるかというと、小数点以下切捨て。
普通なら Math.floor() を使っちゃうところですが、|0 でできるらしいです。
『|』はビットの論理和なので、|0 したところで、そのままの値が返ってきそうなものですが、
javascriptの論理和は不動小数点を整数に変換してから処理するようです*3。
参考:ビット演算子 - 演算子 - JavaScript入門
つまり、整数に変換された時点で小数点以下が切捨てられ、
あとはそのままの値が返ってくるということだと思います。
ちなみに、実行時間的にも Math.floor より速そうです*4。
マシンスペックとかブラウザにもよりそうなので、明言は避けときますが、
自分の環境だと、Math.floor() や parseInt() よりも明らかに『|0』の方が速かったです。
とは言っても、1回使う分にはまったく気にする必要はないですが。
計測に使ったコードは以下。
var s = (new Date).getTime(); for (var i=0; i<1000000; i++) { var val = 3.2|0; //var val = Math.floor(3.2); //var val = parseInt(3.2); } var e = (new Date).getTime(); alert(e-s);
-
-
- -
-
長々と書いたけど、結局は
var ts = Math.floor((new Date).getTime()/1000);
これが、
var ts = new Date/1000|0;
こんな風に書けるんだー、すごい!短くてステキ! という話し。