Javascriptで階層が深いオブジェクト変数をリファレンスエラーにならずに存在チェックする方法
タイトル長い。
JSONなどで、階層が深いオブジェクトを使う時があると思います。そういうときに便利な関数。
■先にコード
まあコード見つけたので丸パクリというかほぼ転載です。
コード元:https://blog.mach3.jp/2016/12/05/ac2016-05.html
こちらをjqueryなしバージョンにしておきました。
var flg = ischeck_dig("obj.hoge1.hoge2.hoge3");
function ischeck_dig(path){
var a,b;
a = window;
path = path.split(".");
for(b in path){
if(a === void 0){ break; }
if(!a[path[b]]){
a = void 0;
break;
}
a = a[path[b]];
}
return a;
}
■説明
JSONなどで、階層が深いオブジェクトを使う時があると思います。
↓こんなの
var obj = {
"fir":{
"sec":{
"thi":"入ってるよ!"
}
}
}この場合、変数を「obj.fir.sec.thi」と書くと呼び出すことができます。便利だね!
しかし存在チェックをする場合は「obj.fir.sec.thi != undefined」としてもダメな時があります。
例えば「obj.hoge1.hoge2.hoge3」等を存在チェックするとどうなるでしょうか?
答えはリファレンスエラーになり、undefinedすら帰ってこず、コードが止まります。(参照エラーともいう)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors/Undefined_prop
「obj.hoge1.hoge2.hoge3」と書くと、obj.hoge1が存在なし(undefined)、obj.hoge1.hoge2は存在なしのところから参照しようとしているので、リファレンスエラーになるということです。
これを回避するためには、URLにも書かれている通りhoge1を作ってからhoge2の存在チェックをするか、エラーが起きる前に止めるしかありません。
エラーを起こさないように普通に書くとこうなります。
if(obj){
if(obj.hoge1){
if(obj.hoge1.hoge2){
…うん、無理。面倒すぎる。
ということで関数でやりましょう。Rubyにはdigという便利な命令があります。
簡単に言えば「深い階層にある値を取得できて、Keyが見つからない場合もエラーにならずにNULLを返す」命令です。今回のやりたいことそのものですね!
それをjqueryで実装した人がいるのをみつけて、それをjqueryなしにしたのが今回のコードです。使えない時もあるからねjquery…
var flg = ischeck_dig("obj.hoge1.hoge2.hoge3");
function ischeck_dig(path){
var a,b;
a = window;
path = path.split(".");
for(b in path){
if(a === void 0){ break; }
if(!a[path[b]]){
a = void 0;
break;
}
a = a[path[b]];
}
return a;
}使う機会なさそうだからobjは取っちゃいました。つけたい人は元コードをみるのじゃ。(投げやり)
引数は文字列にします。関数内でsplitして、順番に存在チェックをしていく形。
void 0っていうのはundefinedのことです。
これでめんどくさいのとはおさらばできそう。
なぜ記事にしたかって?元コードがある記事が検索で全然引っかからなかったからだよ…検索仕方が悪かったのもあるけど。