knowledge base

マークアップ/フロントエンドエンジニアのWEB制作における備忘録です。平日はWEB屋、休日は社会人劇団の主宰・劇作家をしています。

nullを参照してしまったら

try~catchを活用

たとえば、ユーザーエージェントからIEのバージョンを判別します。

var ua = window.navigator.appVersion.toLowerCase();
var appVersion = parseFloat(ua.match(/msie(\s)?(\d+)/i)[2]);

String.matchメソッドの戻り値は、正規表現の後方参照についてまとめた記事をご参照ください。

配列の3番目には、(\d+)にマッチした、バージョンを表す数値が格納されています。

if(appVersion < 9){
    console.log("This is Low IE");
}else{
    console.log("This is Modern Browser");
}

ちなみに一例として、IE8のユーザーエージェントは次の通りです。

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0;....)

MSIEという文字列のないIE10以上や、他のブラウザのとき、ELSE内のプログラムが実行されると思いがちですが、実際は全く異なる結果が返ってきます。

[ex. Google Chromeの場合]

var ua = window.navigator.appVersion.toLowerCase();
// Cannot read property '2' of null というエラーが発生 var appVersion = parseFloat(ua.match(/msie(\s)?(\d+)/i)[2]);  if(appVersion < 9){ console.log("This is Low IE"); }else{ console.log("This is Modern Browser"); }

エラーを起こすだけなら良いのですが、これ以後の処理が実行されなくなってしまいます。

理由は、String.matchメソッドの仕様にあります。

matchメソッド戻り値は、マッチしなかったらnullを返します。

マッチしたかしなかったかというだけの条件分岐なら問題ないのですが、マッチした部分文字列を参照するとなると話は異なります。

nullの中の3番目の要素を参照するという、JavaでいうArrayIndexOutOfBoundsExceptionのような現象が起き、エラーとして扱われてしまうのです。

ならばJava同様、try~catchを利用してしまえばよいのです。

なぜなら先ほど「のような」と書かせていただきましたが、実際のところこれは例外に他ならないためです。

とりあえず今回は、MSIEという文字列を含まないモダンブラウザならば9という数値を代入します。

var ua = window.navigator.appVersion.toLowerCase();
try{
    var appVersion = parseFloat(ua.match(/msie(\s)?(\d+)/i)[2]);
}catch(e){
    var appVersion = 9;
}
if(appVersion < 9){
    console.log("This is Low IE");
}else{
    console.log("This is Modern Browser");
}

これで、例外が投げられても代替となる値が代入され、後続する処理も実行されます。

try~catchは今回のようなケースに限らず、様々な場面で使えますので、ぜひ例外処理やエラーの補足に使ってみてください。

1ラインで書きたい場合

OR演算子と代入を組み合わせて用います。

var ua = window.navigator.appVersion.toLowerCase();
var appVersion = parseFloat(ua.match(/msie(\s)?(\d+)/i)[2]) || 9;
if(appVersion < 9){
    console.log("This is Low IE");
}else{
    console.log("This is Modern Browser");
}