2011-01-13 10 views

risposta

32

In generale, è possibile utilizzare if(property in object), ma questo sarebbe ancora scomodo per i membri nidificati.

Si potrebbe scrivere una funzione:

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

Sembra buono. Mi piace l'approccio ciclico, ma come fa esattamente il __typeof obj === "object" __ help? Non è vero che typeof può restituire l'oggetto anche per null e array? – JustcallmeDrago

+0

@JustcallmeDrago: True ... non ha importanza per l'array, ma fallisce per 'null'. Quindi è forse meglio aggiungere anche un assegno per null. Ho aggiunto il test perché "valore" in "genererebbe un errore. Aggiunto test 'null'. –

+0

@Felix: vedo. Mi piace molto la stringa come argomento, ma anche la semplicità della risposta di Patrick. Il suo è al sicuro come il tuo? È veloce? – JustcallmeDrago

2

Qualcosa di simile (attenzione: codice non testato avanti)

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

Dovrebbe essere 'proplist.length'. –

+0

@Felix - grazie, risolto.Inoltre, vedi la risposta di Phrogz per un'alternativa a hasOwnProperty – Malvolio

+0

Vedere il commento alla mia risposta, anche il tuo sarebbe fallito se 'obj' è' null'. –

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

o simile:

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

Questo non 'lavoro' se del caso particolare valore sembra essere null, false, 0 o "" (una stringa vuota), ma con la possibile eccezione del valore finale, sembra improbabile che sia così.

Inoltre, notare che typeof ____ !== "undefined" non è il test corretto per verificare se un oggetto ha una proprietà. Invece dovresti usare ___ in object, ad es. if ("member" in someObject). Questo perché è possibile impostare una proprietà su un valore esplicito di undefined, che è diverso dalla sua rimozione con delete someObject.member.

4

Ecco un modo: http://jsfiddle.net/9McHq/

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

alert(result); 
+0

Bello. Sicuramente questo può essere trasformato in una funzione ricorsiva abbastanza facilmente! – JustcallmeDrago

5

Si potrebbe anche provare/catch TypeError?

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

Theres una funzione safeRead definita here on thecodeabode che permette una safeRead di proprietà nidificate cioè

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

se una delle proprietà sono nulli o undefined viene restituita una stringa vuota - utile per la formattazione/interpolazione stringa

+0

Mi piace molto questa soluzione – Sukima

+0

Questo codice è scritto male e non funziona. – Coldstar

0

Se è possibile utilizzare lodash libreria, ha una soluzione molto elegante, hasIn.

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

per esempio,

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