JavaScript, façon élégante de vérifier les propriétés des objets imbriqués Pour NULL / undefined [dupliquer]

cette question a déjà une réponse ici:

un "problème" que j'ai chaque maintenant et puis, c'est que j'ai un objet, par ex. user = {} et en travers du cours de l'utilisation de l'application, ce est renseigné. Disons quelque part, après un appel AJAX ou quelque chose que je fais ceci:

user.loc = {
    lat: 50,
    long: 9
}

À un autre endroit, je veux vérifier si user.loc.lat existe.

if(user.loc.lat) {
    // do something
}

Si elle n'existe pas, cela provoquerait une erreur. Si user.loc.lat est undefined , user.loc est bien sûr undefined .

"Cannot read property 'lat' of null" - Dev Tools error

cela signifie que je dois le vérifier comme ceci:

if(user.loc) {
    if(user.loc.lat) {
        // do something
    }
}

ou

if(user.loc && user.loc.lat) {
    // do something
}

ce n'est pas vraiment joli et plus mes objets sont gros, plus ils sont mauvais - évidemment (imaginez 10 niveaux de nidification). Cela me dérange que if(user.loc.lat) ne soit pas simplement retourner false si user.loc est undefined ainsi.

Quelle est la meilleure façon de vérifier ce genre de situation?

71
demandé sur ProblemsOfSumit 2014-05-22 17:55:33

4 réponses

vous pouvez utiliser une fonction utilitaire comme celle-ci:

get = function(obj, key) {
    return key.split(".").reduce(function(o, x) {
        return (typeof o == "undefined" || o === null) ? o : o[x];
    }, obj);
}

Utilisation:

 get(user, 'loc.lat')     // 50
 get(user, 'loc.foo.bar') // undefined

ou, pour vérifier seulement si une propriété existe, sans obtenir sa valeur:

has = function(obj, key) {
    return key.split(".").every(function(x) {
        if(typeof obj != "object" || obj === null || ! x in obj)
            return false;
        obj = obj[x];
        return true;
    });
}

if(has(user, 'loc.lat')) ...
104
répondu georg 2014-05-22 14:25:27

javascript a try-catch. Selon ce que vous devez réellement faire (c.-à-d. à quoi ressemblerait votre énoncé else s'il s'agit de undefined ), c'est peut-être ce que vous voulez.

exemple:

try {
   user.loc.lat.doSomething();
} catch(error) {
   //report
}
17
répondu MarioDS 2014-05-22 13:58:28

vous pouvez combiner les contrôles en utilisant paressy and :

if(user.loc && user.loc.lat) { ...

Ou bien, vous utilisez CoffeeScript et écrire

user.loc?.lat ...

qui exécuterait les contrôles pour la propriété loc et la sauvegarde contre les objets vides.

5
répondu punund 2014-05-22 14:00:57

Essayez cette if(user && user.loc && user.loc.lat) {...}

vous pouvez vérifier la valeur de null et non défini en utilisant type de

si .loc a une valeur false que vous pouvez essayer

if(user && user.loc && typeof(user.loc)!=="undefined"){...}

si vous avez un objet énorme niché que d'avoir un regard à

Source .

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.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

Maj: Essayez lodash.obtenir

4
répondu Aamir Afridi 2017-05-23 12:10:31