2017-05-04 7 views
2

In Javascript mit verschachtelten Objekten mit und ich ständig Sachen wieGibt es eine Kurzform für die Referenz für verschachtelte Objekte?

täte
const configDoc = Config && Config.Settings && Config.Settings.Group && 
    Config.Settings.Group.theThingIReallyWanted 

Gibt es eine Abkürzung für die verschachtelte Referenz zu bekommen?

+0

nicht als Teil der Sprache, Nr. * Edit *, es sei denn, es gibt einen neuen Syntax-Trick, den ich vergesse. – Pointy

+0

Nicht wirklich, aber es ist nicht so schwer zu schreiben – Icepickle

+0

Willst du es 'undefined' zurückgeben, wenn eine dieser Eigenschaften nicht existiert? Denn das wirst du bekommen. Ich mag es, wenn möglich, leere Objekte zurückzugeben, so: 'return (((Config || {}). Einstellungen || {}). Group || {}) .theThingIReallyWanted || {}); ' – Chris

Antwort

1

Leider gibt es keine Kurzschrift für den sicheren Zugriff verschachtelter Eigenschaften in Javascript. Einige Funktionsbibliotheken bieten jedoch Hilfsfunktionen für Ihr Problem (neben anderen nützlichen Funktionen). Beispiel (lodash):

return _.get(Config, 'Settings.Group.theThingIReallyWanted'); 
+0

Ich werde diese Antwort verwenden. Mit Lodash können Sie auch nur das benötigte Modul importieren. https://www.npmjs.com/package/lodash.get – JoshJoe

1

afaik gibt es keine Stenografie ist, aber man könnte versuchen, fangen verwenden zu vermeiden Bedingungen Verkettungs ...

var test = { a: '', b: { c: {} } } 

try { 
    return test.b.c; 
} catch (e) { 
    return undefined; 
} 

Cheerio :)

+0

Vielleicht muss ich nur eine Funktion schreiben, die dies tut, und dann, wenn ich es tun möchte, übergeben Sie einfach die Referenz als Variable. – JoshJoe

+0

eine Funktion, die einen Versuch zu fangen für Sie? Wenn es sich lohnt, 2-3 Zeilen Code zu speichern - warum nicht, aber vielleicht möchten Sie verschiedene Dinge zurückgeben, wenn Sie in verschiedenen Funktionen in Catch-Block laufen - so bis zu Ihnen;) – MarcelD

0

einen Versuch catch-Block verwenden könnte helfen:

try { 
    return Config.Settings.Group.theThingIReallyWanted; 
} catch(e) { 
    // something is undefined 
} 

Es gibt keine einfache Möglichkeit, rekursiv zu prüfen, ob ein Wert definiert ist.

+0

Dies könnte unglückliche Auswirkungen auf die Leistung haben. –

1

Sie können alle Objekte erweitern und eine Erweiterung hinzufügen. Ich weiß, dass Leute dazu neigen, den Object-Prototyp für erweiterte Objektfunktionen zu missbrauchen, aber ich finde nichts leichter als das. Plus, es ist jetzt mit der Object.defineProperty Methode erlaubt.

Object.defineProperty(Object.prototype, "has", { value: function(needle) { 
    var obj = this; 
    var needles = needle.split("."); 
    for(var i = 0; i<needles.length; i++) { 
     if(!obj.hasOwnProperty(needles[i])) { 
      return false; 
     } 
     obj = obj[needles[i]]; 
    } 
    return true; 
}}); 

Um nun für jede Eigenschaft in einem Objekt zu testen, können Sie einfach tun:

if(obj.has("some.deep.nested.object.somewhere")) 

Here's a jsfiddle es zu testen, und insbesondere enthält es einige jQuery, dass, wenn Sie das ändern bricht Object.prototype direkt, weil die Eigenschaft aufzählbar wird. Dies sollte mit Bibliotheken von Drittanbietern funktionieren.

+2

Ich mag was du hier gemacht hast. Um ehrlich zu sein, habe ich auf eine neue ES6 ES7-Kurzschrift gehofft, die das tun würde. Ich bin nicht scharf auf die Idee, den Prototyp zu verwenden, aber das ist wahrscheinlich nur meine natürliche Neigung. – JoshJoe

1

Sie coould die angegebenen Tasten durchlaufen und entweder den Wert oder ein Objekt als Standardeinstellung zurück. später die letzte Eigenschaft zurückgeben.

function getValue(o, path) { 
 
    return path.reduce(function (o, k) { 
 
     return (o || {})[k]; 
 
    }, o); 
 
} 
 

 
var o = { Config: { Settings: { Group: { theThingIReallyWanted: 42 } } } }; 
 

 
console.log(getValue(o, ['Config', 'Settings', 'Group', 'theThingIReallyWanted'])); // 42

+0

Ich habe ein Gefühl, ich sah eine ähnliche Antwort von dir irgendwo schon, aber nicht sicher :) – Icepickle

+1

@Icepickle, ist Ihr Gefühl richtig, aber die Frage war leicht anders. –

Verwandte Themen