863 votes

javascript test pour l'existence de l'objet imbriqué clé

Si j'ai une référence à un objet -

var test = {};

qui seront potentiellement (mais pas immédiatement) ont des objets imbriqués, quelque chose comme:

{ level1:{level2:{level3:'level3'}} };

quelle est la meilleure façon de tester l'existence de touches dans le plus profondément imbriqués les objets?

Ce -

alert(test.level1);

retourne 'undefined', mais cette -

alert(test.level1.level2.level3);

échoue.

Je suis en train de faire quelque chose comme ça -

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

mais je me demandais si il ya une meilleure façon.

716voto

CMS Points 315406

Vous avez à faire étape par étape, si vous ne voulez pas un TypeError, parce que si l'un des membres est - null ou undefined, et vous essayez d'accéder à un membre d'une exception sera levée.

Vous pouvez soit simplement catch l'exception, ou de faire une fonction pour tester l'existence de plusieurs niveaux, quelque chose comme ceci:

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

  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

378voto

Gabe Moothart Points 12400

Voici un modèle que j'ai ramassé à partir de Oliver Steele:

var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
alert( level3 );

En fait, que l'ensemble de l'article est une discussion de la façon dont vous pouvez le faire en javascript. Il s'installe sur l'utilisation de la syntaxe ci-dessus (ce qui n'est pas difficile à lire, une fois que vous vous habituez à elle) comme idiome.

289voto

Austin Pray Points 620

lodash les utilisateurs peuvent profiter de lodash.contrib qui a un couple de méthodes qui permettent d'atténuer ce problème.

getPath

Signature: _.getPath(obj:Object, ks:String|Array)

Obtient la valeur à n'importe quelle profondeur dans un objet imbriqué fondée sur le chemin décrit par la remise des clés. Les touches peuvent être donné comme un tableau ou comme un point de chaîne séparée. Les retours undefined si le chemin ne peut pas être atteint.

var countries = {
        greece: {
            athens: {
                playwright:  "Sophocles"
            }
        }
    }
};

_.getPath(countries, "greece.athens.playwright");
// => "Sophocles"

_.getPath(countries, "greece.sparta.playwright");
// => undefined

_.getPath(countries, ["greece", "athens", "playwright"]);
// => "Sophocles"

_.getPath(countries, ["greece", "sparta", "playwright"]);
// => undefined

46voto

kennebec Points 33886

Vous pouvez facilement lire une propriété de l'objet à n'importe quelle profondeur, si vous manipulez le nom comme une chaîne de caractères: 't.level1.level2.level3'.

window.t={level1:{level2:{level3: 'level3'}}};

function deeptest(s){
    s= s.split('.')
    var obj= window[s.shift()];
    while(obj && s.length) obj= obj[s.shift()];
    return obj;
}

alert(deeptest('t.level1.level2.level3') || 'Undefined');

Il retourne undefined si l'un des segments est - undefined.

21voto

user187291 Points 28951

que diriez -

try {
   alert(test.level1.level2.level3)
} catch(e) {
 ...whatever

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X