2016/07/07

【JavaScript】ネストされたObjectのキーが存在するかチェックする

JavaScriptでObjectを利用するとき、キーが存在するかどうかをチェックしてからでないと「Uncaught TypeError: Cannot read property 'hoge' of undefined」というエラーは発生してしまう。

これを解決するためには、以下のようなクソダサ実装をしなければならない。
if (obj && obj.parent && obj.parent.child && obj.parent.child.grandchild) {
    // ここでようやく安全にobj.parent.child.grandchildにアクセスできる
}

あまりにもクサくて、ダサすぎる…。
今は4階層だが、これが長いキーだったり、もっと階層が深かったりすると見ていられない。

ということで、ネストされたObjectのキーが存在するかどうかチェックする方法を考えてみた。



ネストされたObjectのキーをチェックする



以下のようなオブジェクトがあるとする。
// object
const obj = {
    parent: {
        child: {
            grandchild: 'あるよ',
            grandchild1: '1',
            grandchild2: '2'
        },
        child2: {}
    }
};
const lookup = function _lookup (obj, path) {
 const keys = path.split('.');
  for (let k in keys) {
    const key = keys[k];

    if (!obj.hasOwnProperty(key)) { return false; }

    if (keys.length > 1) {
      return _lookup(obj[key], keys.splice(1).join('.'));
    }
    return true;
  }
};

// テスト
console.log(  lookup(obj, 'parent')    ); // -> true
console.log(  lookup(obj, 'parent1')   ); // -> false
console.log(  lookup(obj, 'parent.child')   ); // -> true
console.log(  lookup(obj, 'parent.child2')  ); // -> true
console.log(  lookup(obj, 'parent.hoge')    ); // -> false
console.log(  lookup(obj, 'parent.child.grandchild')   ); // -> true
console.log(  lookup(obj, 'parent.child.grandchild1')  ); // -> true
console.log(  lookup(obj, 'parent.child.huga')         ); // -> false

lookup(obj, 'path')のように呼び出すことで、キーが存在すればtrue、なければfalseになる。
やっていることは、渡されたpath(parent.child.grandchild)分ループして、オブジェクトに存在するかどうかをobj.hasOwnProperty()で確認し、それを再帰的に呼び出しているだけ。


ちなみに、lodashを導入すれば_.get(obj, 'parent.child.grandchild')で該当するキーの値を取得できる。(実装し終わってからあることに気づいた…)



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿