1. ホーム
  2. ジャバスクリプト

[解決済み】ネストされたJavaScriptオブジェクトのキーが存在するかどうかをテストする

2022-03-23 23:23:32

質問

あるオブジェクトへの参照がある場合。

var test = {};

のような、ネストされたオブジェクトを持つ可能性がある(すぐにではない)ものです。

{level1: {level2: {level3: "level3"}}};

深くネストされたオブジェクトのプロパティの存在を確認する最も良い方法は何ですか?

alert(test.level1); 収穫 undefined しかし alert(test.level1.level2.level3); は失敗します。

現在、このようなことをやっています。

if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
    alert(test.level1.level2.level3);
}

が、もっといい方法はないかと考えていました。

どのように解決するのですか?

を使いたくないなら、一歩一歩やるしかない。 TypeError なぜなら、もしメンバーの1人が null または undefined で、そのメンバーにアクセスしようとすると、例外がスローされます。

単純に catch という例外を発生させるか、以下のような複数レベルの存在をテストする関数を作成します。

function checkNested(obj /*, level1, level2, ... levelN*/) {
  var args = Array.prototype.slice.call(arguments, 1);

  for (var i = 0; i < args.length; i++) {
    if (!obj || !obj.hasOwnProperty(args[i])) {
      return false;
    }
    obj = obj[args[i]];
  }
  return true;
}

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false

ES6 UPDATEです。

以下は、ES6の機能と再帰を使用した、オリジナルの関数の短縮版です(こちらも 適切なテールコール の形式)。

function checkNested(obj, level,  ...rest) {
  if (obj === undefined) return false
  if (rest.length == 0 && obj.hasOwnProperty(level)) return true
  return checkNested(obj[level], ...rest)
}

しかし、ネストされたプロパティの存在を確認するだけでなく、その値を取得したい場合、ここに簡単な一行関数があります。

function getNested(obj, ...args) {
  return args.reduce((obj, level) => obj && obj[level], obj)
}

const test = { level1:{ level2:{ level3:'level3'} } };
console.log(getNested(test, 'level1', 'level2', 'level3')); // 'level3'
console.log(getNested(test, 'level1', 'level2', 'level3', 'length')); // 6
console.log(getNested(test, 'level1', 'level2', 'foo')); // undefined
console.log(getNested(test, 'a', 'b')); // undefined

上記の関数では、ネストされたプロパティの値を取得することができますが、そうでない場合は、以下のようになります。 undefined .

update 2019-10-17です。

任意連鎖の提案 でステージ3に到達しました。 ECMAScript委員会プロセス というトークンを使用することで、深くネストされたプロパティに安全にアクセスできるようになります。 ?. は、新しい オプションの連鎖演算子 :

const value = obj?.level1?.level2?.level3 

アクセスされたレベルのいずれかが null または undefined を指定すると、式は次のように解決されます。 undefined を単体で使用します。

また、この提案により、メソッドコールを安全に処理することができます。

obj?.level1?.method();

上記の式で生成されるのは undefined もし obj , obj.level1 または obj.level1.methodnull または undefined そうでない場合は関数を呼び出します。

この機能は、Babelで オプションのチェーニングプラグイン .

以来 バベル 7.8.0 ES2020 はデフォルトでサポートされています。

確認 この例 をBabel REPLに追加しました。

?UPDATE:2019年12月?

オプションチェイニング案がついに ステージ4に到達 を2019年12月のTC39委員会にて発表しました。これは、この機能が ECMAScript 2020 規格です。