Ari
En mi código, trato con una matriz que tiene algunas entradas con muchos objetos anidados unos dentro de otros, mientras que otros no. Se parece a lo siguiente:
// Where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
Esto me está dando problemas, porque necesito iterar a través de la matriz a veces, y la inconsistencia me arroja errores como este:
for (i=0; i<test.length; i++) {
// OK, on i==0, but 'cannot read property of undefined' on i==1
console.log(a.b.c);
}
Soy consciente de que puedo decir if(a.b){ console.log(a.b.c)}
, pero esto es extraordinariamente tedioso en los casos en que hay hasta 5 o 6 objetos anidados unos dentro de otros. ¿Hay alguna otra manera (más fácil) de que pueda tenerlo? solo Hacer el console.log
si existe, pero sin tirar un error?
calle
Actualizar:
- Si usa JavaScript de acuerdo con ECMAScript 2020 o posterior, consulte encadenamiento opcional.
- TypeScript ha agregado soporte para encadenamiento opcional en la versión 3.7.
// use it like this
obj?.a?.lot?.of?.properties
Solución para JavaScript anterior a ECMASCript 2020 o TypeScript anterior a la versión 3.7:
Una solución rápida es usar una función auxiliar de prueba/captura con ES6 función de flecha:
function getSafe(fn, defaultVal) {
try {
return fn();
} catch (e) {
return defaultVal;
}
}
// use it like this
console.log(getSafe(() => obj.a.lot.of.properties));
// or add an optional default value
console.log(getSafe(() => obj.a.lot.of.properties, 'nothing'));
-
¡Me encanta! lo único que agregaría es una consola. advertir dentro de la captura, para que sepa del error pero continúa.
– Rabino Shuki Gur
11 de diciembre de 2018 a las 10:31
-
Atrapando todo excepciones sin volver a lanzar es maloy, en general, usar excepciones como parte del flujo de ejecución esperado tampoco es excelente, aunque en este caso está bastante bien contenido.
– hugo
25 de agosto de 2019 a las 11:28
-
¡Oh hombre, ahora eres mi héroe! try and catch lo hizo por mí después de todos mis esfuerzos fallidos con Object.assign, el operador ‘OR’, el operador ternario, etc., nada funciona en presencia de un error indefinido. ¡¡Gracias!!
– usuario7622147
11 de febrero de 2022 a las 15:11
benjamin grünbaum
Lo que está haciendo plantea una excepción (y con razón). Siempre puedes hacer:
try{
window.a.b.c
}catch(e){
console.log("YO",e)
}
Pero no lo haría, en lugar de eso, piense en su caso de uso.
¿Por qué está accediendo a datos, 6 niveles anidados que no conoce? ¿Qué caso de uso justifica esto?
Por lo general, le gustaría validar con qué tipo de objeto está tratando.
Además, en una nota al margen, no debe usar declaraciones como if(a.b)
porque devolverá falso si ab es 0 o incluso si es “0”. En su lugar, compruebe si a.b !== undefined
-
Con respecto a su primera edición: está justificada; Estoy tratando con entradas de bases de datos estructuradas JSON, de modo que los objetos escalarán múltiples niveles de campos (es decir, entradas.usuarios.mensajes.fecha, etc., donde no todos los casos tienen datos ingresados)
– Ari
8 de febrero de 2013 a las 22:23
-
“devolverá verdadero si ab es 0” – no.
typeof a.b === "undefined" && a.b!=null
– no es necesario hacer la segunda parte después de la primera, y tiene más sentido simplemente hacerif ("b" in a)
– Ian
8 de febrero de 2013 a las 22:23
-
@Ian, sí, obviamente lo dije en serio al revés, devolverá falso incluso si ab es “0”. Buena atrapada
– Benjamin Grünbaum
8 de febrero de 2013 a las 22:24
-
@BenjaminGruenbaum Suena bien, no estaba seguro de si lo decía en serio. Además, creo que quieres
typeof a.b !
== “indefinido” && ab!=null` – observe el!==
– Ian
8 de febrero de 2013 a las 22:26
-
Si no quiere aburrirse de ab && abc && console.log(abc), entonces esta es la única manera de registrar incógnitas consistentemente.
– Brian Cray
08/02/2013 a las 22:31
matt weiss
Si entiendo su pregunta correctamente, desea la forma más segura de determinar si un objeto contiene una propiedad.
La forma más fácil es usar el in
operador.
window.a = "aString";
//window should have 'a' property
//lets test if it exists
if ("a" in window){
//true
}
if ("b" in window){
//false
}
Por supuesto, puedes anidar esto tan profundo como quieras.
if ("a" in window.b.c) { }
No estoy seguro si esto ayuda.
-
No puedes anidar esto con seguridad tan profundamente como quieras. Y si
window.b
¿es indefinido? Obtendrá un error de tipo:Cannot use 'in' operator to search for 'c' in undefined
– Trevor
28 de agosto de 2017 a las 23:34
sean chen
Prueba esto. Si a.b
es undefined
dejará el if
declaración sin ninguna excepción.
if (a.b && a.b.c) {
console.log(a.b.c);
}
tehwalris
Si estás usando lodashpodrías usar su has
función. Es similar al nativo “in”, pero permite caminos.
var testObject = {a: {b: {c: 'walrus'}}};
if(_.has(testObject, 'a.b.c')) {
//Safely access your walrus here
}
-
Mejor, podemos usar
_.get()
con predeterminado para fácil lectura:_.get(object, 'a.b.c', 'default');
– Si no
18 de junio de 2018 a las 13:53
Pedro Mortensen
Si utiliza Babelya puede usar la sintaxis de encadenamiento opcional con @babel/plugin-proposal-opcional-encadenamiento Complemento de Babel. Esto le permitiría reemplazar esto:
console.log(a && a.b && a.b.c);
con este:
console.log(a?.b?.c);
-
Mejor, podemos usar
_.get()
con predeterminado para fácil lectura:_.get(object, 'a.b.c', 'default');
– Si no
18 de junio de 2018 a las 13:53
Pedro Mortensen
Si usted tiene Lodashpuedes usar su .get
método:
_.get(a, 'b.c.d.e')
O darle un valor predeterminado:
_.get(a, 'b.c.d.e', default)
-
Hola, ¿eso también puede capturar la propiedad de error nulo?
– Jovylle
7 abr 2022 a las 16:22
El error es probablemente una excepción de Javascript regular, así que pruebe el
try..catch
declaración. Dicho esto, una matriz que contiene elementos tremendamente heterogéneos me parece un problema de diseño.– milimoose
8 de febrero de 2013 a las 22:17
Si su estructura no es consistente en todos los elementos, ¿qué hay de malo en verificar la existencia? De verdad, usaría
if ("b" in a && "c" in a.b)
. Puede ser “tedioso”, pero eso es lo que obtienes por inconsistencia… lógica normal.– Ian
8 de febrero de 2013 a las 22:21
¿Por qué accedería a propiedades que no existen? ¿Por qué no sabe cómo son los objetos?
– Bergi
8 de febrero de 2013 a las 22:22
Puedo entender por qué alguien no querría que un error colapsara todo. No siempre se puede confiar en que las propiedades de un objeto existan o no existan. Si tiene algo en su lugar que puede manejar el evento de que el objeto tiene un formato incorrecto, entonces su código es mucho más eficiente y menos frágil.
– SSH Esto
09/04/2013 a las 20:19
Te sorprendería saber cuántos objetos/matrices tienen una forma incorrecta en situaciones de la vida real.
– Una pregunta más
8 de septiembre de 2017 a las 2:42