error - null javascript
JavaScript, forma elegante de verificar propiedades de objetos anidados para NULL/indefinido (4)
Esta pregunta ya tiene una respuesta aquí:
un "problema" que tengo de vez en cuando es que tengo un objeto, por ejemplo, user = {}
y durante el uso de la aplicación esto se llena. Digamos en algún lugar, después de una llamada AJAX o algo que hago esto:
user.loc = {
lat: 50,
long: 9
}
En otro lugar, quiero verificar si user.loc.lat
existe.
if(user.loc.lat) {
// do something
}
Si no existe, esto causará un error. Si user.loc.lat
undefined
está undefined
, user.loc
, por supuesto, user.loc
está undefined
.
"Cannot read property ''lat'' of null" - Dev Tools error
Eso significa que necesito verificarlo así:
if(user.loc) {
if(user.loc.lat) {
// do something
}
}
o
if(user.loc && user.loc.lat) {
// do something
}
Esto no es realmente bonito y cuanto más grandes son mis objetos, peor se pone, obviamente (imagine 10 niveles de anidación). Me da if(user.loc.lat)
que if(user.loc.lat)
no solo devuelva false
si user.loc
está undefined
.
¿Cuál es la forma ideal de verificar situaciones como esta?
Bueno, javascript tiene try-catch. Dependiendo de lo que realmente necesite hacer (es decir, cómo se vería su declaración si no está undefined
), eso podría ser lo que desea.
ejemplo:
try {
user.loc.lat.doSomething();
} catch(error) {
//report
}
Pruebe esto if(user && user.loc && user.loc.lat) {...}
Puede verificar el valor de nulo e indefinido utilizando typeof
Si .loc
tiene un valor false
que puedes probar
if(user && user.loc && typeof(user.loc)!=="undefined"){...}
Si tiene un objeto anidado enorme que echar un vistazo a
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
Actualización: prueba lodash.get
Puede combinar los cheques usando perezoso and
:
if(user.loc && user.loc.lat) { ...
O bien, usa CoffeeScript y escribe
user.loc?.lat ...
que ejecutaría los controles para la propiedad loc
y salvaguardar contra objetos vacíos.
Puede usar una función de utilidad como esta:
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
O bien, para verificar solo si existe una propiedad, sin obtener su valor:
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'')) ...