JavaScript, modo elegante per controllare le proprietà degli oggetti nidificati per NULL / non definito

un “problema” che ho ogni tanto è che ho un object, ad es. user = {} e attraverso l’uso dell’app questa viene popolata. Diciamo qualcosa, dopo una chiamata AJAX o qualcosa che faccio questo:

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

In un altro luogo voglio verificare se esiste user.loc.lat .

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

Se non esiste, ciò causerà un errore. Se user.loc.lat undefined è undefined , user.loc ovviamente undefined è undefined .

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

Ciò significa che ho bisogno di controllarlo in questo modo:

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

o

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

Questo non è proprio carino e più i miei oggetti sono peggio – ovviamente (immagina 10 livelli di nidificazione). Mi if(user.loc.lat) che if(user.loc.lat) non restituisca semplicemente false se user.loc è undefined .

Qual è il modo ideale per verificare situazioni come questa?

Puoi usare una funzione di utilità come questa:

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

Uso:

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

Oppure, per controllare solo se esiste una proprietà, senza ottenere il suo valore:

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

Bene, javascript ha provato a catturare. A seconda di ciò che effettivamente devi fare (cioè quale sarebbe la tua else affermazione se non è undefined ), potrebbe essere quello che vuoi.

esempio:

 try { user.loc.lat.doSomething(); } catch(error) { //report } 

È ansible combinare i controlli utilizzando pigro and :

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

Oppure, usi CoffeeScript e scrivi

 user.loc?.lat ... 

che eseguiva i controlli per la proprietà loc e salvaguarda gli oggetti vuoti.

Prova questo if(user && user.loc && user.loc.lat) {...}

Puoi controllare il valore di null e undefined usando typeof

Se .loc ha un valore false quello che puoi provare

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

Se hai un object nidificato enorme di quello che hai visto

Fonte .

 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 

Aggiornamento: prova lodash.get