een “probleem” dat ik af en toe heb, is dat ik een object heb, b.v. user = {}
en tijdens het gebruik van de app wordt dit ingevuld. Laten we ergens zeggen, na een AJAX-oproep of zoiets, doe ik dit:
user.loc = {
lat: 50,
long: 9
}
Op een andere plaats wil ik controleren of user.loc.lat
bestaat.
if (user.loc.lat) {
// do something
}
Als het niet bestaat, zal dit een fout veroorzaken. Als user.loc.lat
undefined
is, is user.loc
natuurlijk ook undefined
.
"Cannot read property 'lat' of null" - Dev Tools error
Dat betekent dat ik het als volgt moet controleren:
if (user.loc) {
if (user.loc.lat) {
// do something
}
}
of
if (user.loc && user.loc.lat) {
// do something
}
Dit is niet echt mooi en hoe groter mijn objecten zijn, hoe erger het wordt – uiteraard (stel je 10 nestniveaus voor).
Ik vind het vervelend dat if(user.loc.lat)
niet alleen false
retourneert als user.loc
undefined
ook.
Wat is de ideale manier om dit soort situaties te controleren?
Antwoord 1, autoriteit 100%
U kunt een hulpprogramma als deze gebruiken:
get = function(obj, key) {
return key.split(".").reduce(function(o, x) {
return (typeof o == "undefined" || o === null) ? o : o[x];
}, obj);
}
Gebruik:
get(user, 'loc.lat') // 50
get(user, 'loc.foo.bar') // undefined
Of, om alleen te controleren of een eigenschap bestaat, zonder de waarde ervan te krijgen:
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')) ...
Antwoord 2, autoriteit 16%
U kunt de controles combineren met behulp van luie and
:
if(user.loc && user.loc.lat) { ...
Of u gebruikt CoffeeScript. En ES2020 heeft een nieuwe syntaxis ( Nullish coalescing Operator ).
user.loc?.lat?. '...'
die de controles voor loc
eigendom zou uitvoeren en zou beschermen tegen lege objecten.
Antwoord 3, autoriteit 16%
Nou javascript heeft try-catch. Afhankelijk van wat u werkelijk moet doen (d.w.z. hoe uw else
-statement eruit zou zien als het undefined
is), is dat misschien wat u wilt.
voorbeeld:
try {
user.loc.lat.doSomething();
} catch(error) {
//report
}
Antwoord 4, autoriteit 4%
Probeer dit if(user && user.loc && user.loc.lat) {...}
U kunt de waarde van null en undefined controleren met typeof
Als .loc
de waarde false
heeft, dan kun je het proberen
if(user && user.loc && typeof(user.loc)!=="undefined"){...}
Als je een enorm genest object hebt, kijk dan eens naar
Bron.
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
Bijwerken:
Probeer lodash.get