2013-08-12 20 views
11

Mam strukturę danych opartą na json z obiektami zawierającymi zagnieżdżone obiekty. Aby uzyskać dostęp do określonego elementu danych, łączyłem ze sobą odwołania do właściwości obiektu. Na przykład:Dostęp do obiektów zagnieżdżonych JavaScript bezpiecznie

var a = b.c.d; 

Jeśli b lub b.c jest niezdefiniowane, spowoduje to błąd z błędem. Jednak chcę uzyskać wartość, jeśli istnieje, inaczej nieokreślona. Jaki jest najlepszy sposób, aby to zrobić bez sprawdzania, czy istnieje każda wartość w łańcuchu?

chciałbym zachować tę metodę jako ogólne, jak to możliwe, więc nie trzeba dodawać ogromnej liczby metod pomocniczych takich jak:

var a = b.getD(); 

lub

var a = helpers.getDFromB(b); 

ja też chcę spróbować aby uniknąć konstrukcji try/catch, ponieważ nie jest to błąd, więc użycie polecenia try/catch wydaje się niewłaściwie umieszczone. Czy to jest rozsądne?

Wszelkie pomysły?

+2

http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key?rq=1 – goat

Odpowiedz

5

Można tworzyć ogólny sposób, że dostęp element w oparciu o tablicę nazw właściwości, który jest interpretowany jako droga przez właściwości:

function getValue(data, path) { 
    var i, len = path.length; 
    for (i = 0; typeof data === 'object' && i < len; ++i) { 
     data = data[path[i]]; 
    } 
    return data; 
} 

Następnie można nazwać go:

var a = getValue(b, ["c", "d"]); 
+0

Biorąc pod uwagę ab === a ['b'] zakładam, że za pomocą ciągów odwołanie do obiektów jest uważane za najlepszą praktykę w JS? – Hubris

+0

@Hubris - Nazwy właściwości są zawsze ciągami. Notacja kropkowa jest uznawana za "cukier syntaktyczny" (który nawet nie działa, jeśli nazwa właściwości jest słowem zastrzeżonym lub nieprawidłowym identyfikatorem JS). –

+0

OK, tak właśnie myślałem. Niesamowite. Dziękuję :) – Hubris

6

Standardowe podejście:

var a = b && b.c && b.c.d && b.c.d.e; 

jest dość szybki, ale nie zbyt elegancka (es szczególnie w przypadku dłuższych nazw właściwości).

Korzystanie z funkcji do przechodzenia przez obiekty obiektu JavaScipt nie jest wydajne ani eleganckie.

Spróbuj to zamiast:

try { var a = b.c.d.e; } catch(e){} 

w przypadku, gdy są pewni, że a nie był wcześniej używany lub

try { var a = b.c.d.e; } catch(e){ a = undefined; } 

w przypadku możesz mieć przypisany wcześniej.

Prawdopodobnie jest to jeszcze szybciej niż pierwsza opcja.

0

Jeśli chcesz mieć dostęp dynamiczny z nieregularną liczbą właściwości, w ES6 możesz łatwo wykonać następujące czynności;

function getNestedValue(o,...a){ 
 
    var val = o; 
 
    for (var prop of a) val = typeof val === "object" && 
 
            val !== null  && 
 
            val[prop] !== void 0 ? val[prop] 
 
                 : undefined; 
 
    return val; 
 
} 
 
var obj = {a:{foo:{bar:null}}}; 
 
console.log(getNestedValue(obj,"a","foo","bar")); 
 
console.log(getNestedValue(obj,"a","hop","baz"));

1

Jest to stary i teraz pytanie z funkcji ES6, problem ten można rozwiązać łatwiej.

const idx = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o); 

Dzięki @sharifsbeat tego solution.

0

prawdopodobnie to może być prosta:

let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}} 
console.log((a || {}).a2); => undefined 
console.log(((a || {}).c1 || {}).d1) => 13 

i tak dalej.

Powiązane problemy