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のことです。
これでめんどくさいのとはおさらばできそう。
なぜ記事にしたかって?元コードがある記事が検索で全然引っかからなかったからだよ…検索仕方が悪かったのもあるけど。