2011-01-13 32 views

Respuesta

32

En general, puede usar if(property in object), pero esto aún sería engorroso para los miembros anidados.

Se podría escribir una función:

function test(obj, prop) { 
    var parts = prop.split('.'); 
    for(var i = 0, l = parts.length; i < l; i++) { 
     var part = parts[i]; 
     if(obj !== null && typeof obj === "object" && part in obj) { 
      obj = obj[part]; 
     } 
     else { 
      return false; 
     } 
    } 
    return true; 
} 

test(someObject, 'member.member.member.value'); 

DEMO

+0

Se ve bien. Me gusta el enfoque de bucle, pero ¿cómo funciona __typeof obj === "object" __ help exactamente? ¿No es cierto que typeof puede devolver objetos para null y array también? – JustcallmeDrago

+0

@JustcallmeDrago: Cierto ... no importaría demasiado para la matriz, pero fallaría para 'null'. Entonces, quizás sea mejor agregar un cheque para nulo también. Agregué la prueba porque ''valor 'en ' arrojaría un error. Se agregó la prueba 'null'. –

+0

@Felix: Ya veo. Realmente me gusta la cuerda como argumento, pero también la simplicidad de la respuesta de Patrick. ¿Es tan seguro como el tuyo? ¿Es tan rápido? – JustcallmeDrago

2

Algo así como (advertencia: código no probado por delante)

var testProperty = function(obj, proplist) { 
    for (var i=0; i < proplist.length; i++) { 
     if (obj.hasOwnProperty(proplist[i])) { 
     obj = obj[proplist[i]]; 
     } else { 
     return false; 
     } 
    } 
    return true; 
} 
+0

debería ser 'proplist.length'. –

+0

@Felix - gracias, arreglado.Además, vea la respuesta de Phrogz para una alternativa a hasOwnProperty – Malvolio

+0

Vea el comentario de mi respuesta, el suyo también fallaría si 'obj' es' nulo'. –

2
if (someObject.member && someObject.member.member && 
    someObject.member.member.member && someObject.member.member.member.value) ... 

o parecida:

var val = foo.bar && foo.bar.jim && foo.bar.jim.jam && foo.bar.jim.jam.value; 

esto no va a 'trabajar' o ningún valor particular, pasa a ser null, false, 0, o "" (una cadena vacía), pero con la posible excepción del valor final, parece poco probable que sea el caso.

Además, tenga en cuenta que typeof ____ !== "undefined" no es la prueba correcta para ver si un objeto tiene una propiedad. En su lugar, debe usar ___ in object, p. if ("member" in someObject). Esto se debe a que puede establecer una propiedad en un valor explícito de undefined, que es diferente de eliminarlo con delete someObject.member.

4

Aquí está una manera: http://jsfiddle.net/9McHq/

var result = ((((someObject || {}).member || {}).member || {}).member || {}).value; 

alert(result); 
+0

Agradable. ¡Seguramente esto se puede convertir en una función recursiva con bastante facilidad! – JustcallmeDrago

5

También puede probar/TypeError truco?

try { 
    console.log(someObject.member.member.member.value); 
} catch(e) { 
    if (e instanceof TypeError) { 
    console.log("Couldn't access someObject.member.member.member.value"); 
    console.log(someObject); 
    } 
} 
2

Hay una función safeRead definido here on thecodeabode que permite una safeRead de propiedades anidadas es decir

safeRead(foo, 'bar', 'jim', 'jam'); 

si cualquiera de las propiedades son nulos o indefinido se devuelve una cadena en blanco - útil para el formato/interpolación de cadenas

+0

Me gusta mucho esta solución – Sukima

+0

Ese código está mal escrito y no funciona. – Coldstar

0

Si puede utilizar lodash biblioteca, que tiene una solución muy elegante, hasIn.

_.hasIn(someObject, 'member.level1.level2.level3'); 

por ejemplo,

var obj = {'x': 999, 'a': {'b': {'c': 123, 'd': 234}}} 
// => undefined 

_.hasIn(obj, 'x') 
// => true 

_.hasIn(obj, 'a.b.d') 
// => true 

_.hasIn(obj, 'a.b.e') 
// => false 
Cuestiones relacionadas