En mi código, trato con una matriz que tiene algunas entradas con muchos objetos anidados entre sí, mientras que algunos 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 decirlo if(a.b){ console.log(a.b.c)}
, pero esto es extraordinariamente tedioso en los casos en los que hay hasta 5 o 6 objetos anidados entre sí. ¿Hay alguna otra forma (más fácil) de hacer que SOLO haga el archivo console.log si existe, pero sin arrojar un error?
javascript
Ari
fuente
fuente
try..catch
declaración. Dicho esto, una matriz que contiene elementos tremendamente heterogéneos me parece un problema de diseño.if ("b" in a && "c" in a.b)
. Puede ser "tedioso", pero eso es lo que obtienes por inconsistencia ... lógica normal.Respuestas:
Actualización :
Solución para JavaScript anterior a ECMASCript 2020 o TypeScript anterior a la versión 3.7 :
Una solución rápida es utilizar una función auxiliar de prueba / captura con la función de flecha ES6 :
Fragmento de trabajo:
Mostrar fragmento de código
Consulte este artículo para obtener más detalles.
fuente
Lo que está haciendo genera una excepción (y con razón).
Siempre puedes hacer
Pero yo no pensaría en su caso de uso.
¿Por qué está accediendo a datos, 6 niveles anidados con los que no está familiarizado? ¿Qué caso de uso justifica esto?
Por lo general, le gustaría validar realmente 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 sia.b !== undefined
fuente
typeof a.b === "undefined" && a.b!=null
- innecesario hacer la segunda parte después de la primera, y tiene más sentido simplemente hacerloif ("b" in a)
typeof a.b !
== "indefinido" && ab! = Null` - observe el!==
Si entiendo su pregunta correctamente, quiere la forma más segura de determinar si un objeto contiene una propiedad.
La forma más sencilla es utilizar el
in
operador .Por supuesto que puedes anidar esto tan profundo como quieras
No estoy seguro si esto ayuda.
fuente
window.b
no está definido? Recibirá un error de tipo:Cannot use 'in' operator to search for 'c' in undefined
Si está usando lodash , podría usar su función "has". Es similar al nativo "in", pero permite rutas.
fuente
_.get()
valor predeterminado para una lectura fácil:_.get(object, 'a.b.c', 'default');
Prueba esto. Si
a.b
no está definido, dejará laif
declaración sin excepción.fuente
Este es un problema común cuando se trabaja con un objeto json profundo o complejo, por lo que trato de evitar try / catch o incrustar múltiples comprobaciones que harían que el código sea ilegible, por lo general uso este pequeño fragmento de código en todo mi procedimiento para hacer el trabajo.
fuente
Si tienes lodash puedes usar su
.get
métodoo darle un valor predeterminado
fuente
Yo uso religiosamente undefsafe . Prueba cada nivel en su objeto hasta que obtiene el valor que solicitó o devuelve "indefinido". Pero nunca errores.
fuente
_.get
Si usa Babel, ya puede usar la sintaxis de encadenamiento opcional con el complemento de Babel @ babel / plugin-proposition-optional-chaining . Esto le permitiría reemplazar esto:
con este:
fuente
Me gusta la respuesta de Cao Shouguang, pero no me gusta pasar una función como parámetro a la función getSafe cada vez que hago la llamada. He modificado la función getSafe para aceptar parámetros simples y ES5 puro.
fuente
getSafe(myObj.x.c)
. Probé las últimas versiones de Chrome y Firefox.En la respuesta de str, el valor 'indefinido' se devolverá en lugar del valor predeterminado establecido si la propiedad no está definida. A veces, esto puede provocar errores. Lo siguiente garantizará que el valor predeterminado siempre se devuelva cuando la propiedad o el objeto no estén definidos.
fuente
Lodash tiene un
get
método que permite un valor predeterminado como tercer parámetro opcional, como se muestra a continuación:fuente
Imagina que queremos aplicar una serie de funciones a
x
si y solo six
no es nulo:Ahora digamos que necesitamos hacer lo mismo para
y
:Y lo mismo para
z
:Como puede ver, sin una abstracción adecuada, terminaremos duplicando el código una y otra vez. Tal abstracción ya existe: la mónada Quizás .
La mónada Maybe tiene tanto un valor como un contexto computacional:
Una implementación ingenua se vería así:
⚠️ ¡Esta implementación es solo para fines ilustrativos! No es así como debería hacerse y está mal en muchos niveles. Sin embargo, esto debería darle una mejor idea de lo que estoy hablando.
Como puede ver, nada se puede romper:
Apéndice 1
No puedo explicar qué son las mónadas ya que este no es el propósito de esta publicación y hay gente mejor que yo en esto. Sin embargo, como dijo Eric Elliot en la publicación de su blog, JavaScript Monads Made Simple :
Apéndice 2
Así es como resolvería su problema usando la mónada Quizás demonetjs
fuente
Respondí a esto antes y hoy estaba haciendo una verificación similar. Una simplificación para comprobar si existe una propiedad con puntos anidados. Puede modificar esto para devolver el valor o algún valor predeterminado para lograr su objetivo.
En su pregunta, podría hacer algo como:
fuente
Yo suelo usar así:
fuente
Puede evitar obtener un error dando un valor predeterminado antes de obtener la propiedad
Esto también funciona muy bien con matrices:
fuente