JavaScript で WebKit 判定
Date.parse() の解釈の違いを利用した WebKit 判定ライブラリ「is-webkit」の紹介と動作原理を解説します。
目次
JavaScript で現在実行中のランタイムが WebKit かどうか判定するライブラリを作りました。
https://www.npmjs.com/package/is-webkithttps://www.npmjs.com/package/is-webkit使い方
import isWebKit from "is-webkit";
console.log(isWebKit()); // -> true or false動作原理
実装は非常にシンプルで、たったのこれだけです。
export default function isWebKit() {
return Date.parse("1969-12-31T23:59:59.9991Z") === 0;
}各種 JavaScript ランタイムは TC39 の仕様通りミリ秒の時刻を浮動小数点数で管理しています。そのため時刻 1969-12-31T23:59:59.9991Z をパースすると内部的には -0.9 になります。これを整数値のミリ秒に変換するとき、WebKit とそれ以外のランタイムで差異があるため、上記の実装で WebKit 判定ができるというわけです。
今後も使えるか不明
TC39 ではミリ秒単位の浮動小数を ToIntegerOrInfinity で整数に変換します。このとき truncate で小数部分を丸めるので、-0.9 は -0 になるはずです。しかし WebKit 以外はまるで truncate ではなく floor を使ったような丸め方 (-0.9 は -1 になる) をしています。仕様については浅くしか見ていませんが、WebKit だけが TC39 に準拠しているように見えます。しかし、おそらく昔からランタイム間で差異がある状態でしょうし、今後も修正はされないのではと思っています。