validacion - validar nombre javascript
¿Cómo evitar ''no puedo leer propiedad de errores indefinidos''? (9)
En la respuesta de str, el valor ''indefinido'' se devolverá en lugar del valor predeterminado establecido si la propiedad no está definida. Esto a veces puede causar errores. Lo siguiente se asegurará de que siempre se devuelva defaultVal cuando la propiedad o el objeto no estén definidos.
const temp = {};
console.log(getSafe(()=>temp.prop, ''0''));
function getSafe(fn, defaultVal) {
try {
if (fn() === undefined) {
return defaultVal
} else {
return fn();
}
} catch (e) {
return defaultVal;
}
}
En mi código, trato con una matriz que tiene algunas entradas con muchos objetos anidados entre sí, mientras que otras no. Se parece algo 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 recorrer la matriz a veces, y la inconsistencia me está arrojando errores de esta manera:
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(ab){ console.log(abc)}
, pero esto es extraordinariamente tedioso en los casos en que hay hasta 5 o 6 objetos anidados uno dentro del otro. ¿Hay alguna otra forma (más fácil) en la que SOLAMENTE pueda hacer la console.log si existe, pero sin lanzar un error?
Este es un problema común cuando se trabaja con un objeto json profundo o complejo, por lo que trato de evitar probar / capturar o incrustar múltiples chequeos que hacen que el código sea ilegible. Generalmente, uso este pequeño código en todo mi proceso para hacer el trabajo.
/* ex: getProperty(myObj,''aze.xyz'',0) // return myObj.aze.xyz safely
* accepts array for property names:
* getProperty(myObj,[''aze'',''xyz''],{value: null})
*/
function getProperty(obj, props, defaultValue) {
var res, isvoid = function(x){return typeof x === "undefined" || x === null;}
if(!isvoid(obj)){
if(isvoid(props)) props = [];
if(typeof props === "string") props = props.trim().split(".");
if(props.constructor === Array){
res = props.length>1 ? getProperty(obj[props.shift()],props,defaultValue) : obj[props[0]];
}
}
return typeof res === "undefined" ? defaultValue: res;
}
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 pensar en su caso de uso.
¿Por qué accede a los datos, 6 niveles anidados de 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(ab)
porque devolverá false si ab es 0 o incluso si es "0". En su lugar, compruebe si ab !== undefined
Prueba esto. Si ab
es undefiend, dejará la sentencia if
sin excepción.
if (a.b && a.b.c) {
console.log(a.b.c);
}
Respondí esto antes y me encontré con un cheque similar hoy. Una simplificación para comprobar si existe una propiedad de puntos anidada. Puede modificar esto para devolver el valor, o algún valor predeterminado para lograr su objetivo.
function containsProperty(instance, propertyName) {
// make an array of properties to walk through because propertyName can be nested
// ex "test.test2.test.test"
let walkArr = propertyName.indexOf(''.'') > 0 ? propertyName.split(''.'') : [propertyName];
// walk the tree - if any property does not exist then return false
for (let treeDepth = 0, maxDepth = walkArr.length; treeDepth < maxDepth; treeDepth++) {
// property does not exist
if (!Object.prototype.hasOwnProperty.call(instance, walkArr[treeDepth])) {
return false;
}
// does it exist - reassign the leaf
instance = instance[walkArr[treeDepth]];
}
// default
return true;
}
En tu pregunta podrías hacer algo como:
let test = [{''a'':{''b'':{''c'':"foo"}}}, {''a'': "bar"}];
containsProperty(test[0], ''a.b.c'');
Si entiendo su pregunta correctamente, desea que la forma más segura de determinar si un objeto contiene una propiedad.
La forma más fácil es usar la declaración "en".
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 que puedes anidar esto tan profundo como quieras.
if ("a" in window.b.c) { }
No estoy seguro si esto ayuda.
Si está usando lodash , podría usar su función "tiene". Es similar al "in" nativo, pero permite rutas.
var testObject = {a: {b: {c: ''walrus''}}};
if(_.has(testObject, ''a.b.c'')) {
//Safely access your walrus here
}
Una solución rápida es utilizar una función de ayuda de prueba / captura con la función de flecha ES6:
function getSafe(fn, defaultVal) {
try {
return fn();
} catch (e) {
return defaultVal;
}
}
// use it like this
getSafe(() => obj.a.lot.of.properties);
// or add an optional default value
getSafe(() => obj.a.lot.of.properties, ''nothing'');
Vea este artículo para más detalles.
Yo uso undefsafe religiosamente. Prueba cada nivel hacia abajo en su objeto hasta que obtiene el valor solicitado o devuelve "indefinido". Pero nunca errores.