In meinem Code beschäftige ich mich mit einem Array, das einige Einträge mit vielen ineinander verschachtelten Objekten enthält, während andere dies nicht tun. Es sieht ungefähr so aus:
// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
Dies gibt mir Probleme, weil ich manchmal durch das Array iterieren muss und die Inkonsistenz mir Fehler wie folgt wirft:
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);
}
Ich bin mir bewusst, dass ich sagen kann if(a.b){ console.log(a.b.c)}
, aber dies ist außerordentlich mühsam in Fällen, in denen bis zu 5 oder 6 Objekte ineinander verschachtelt sind. Gibt es eine andere (einfachere) Möglichkeit, dass ich NUR das console.log ausführen kann, wenn es vorhanden ist, aber ohne einen Fehler auszulösen?
javascript
Ari
quelle
quelle
try..catch
Anweisung. Das heißt, ein Array, das wild heterogene Elemente enthält, scheint mir ein Designproblem zu sein.if ("b" in a && "c" in a.b)
. Es mag "langweilig" sein, aber das ist es, was man für Inkonsistenz bekommt ... normale Logik.Antworten:
Update :
Lösung für JavaScript vor ECMASCript 2020 oder TypeScript älter als Version 3.7 :
Eine schnelle Problemumgehung ist die Verwendung einer Try / Catch-Hilfsfunktion mit ES6- Pfeilfunktion :
Arbeitsausschnitt:
Code-Snippet anzeigen
Weitere Informationen finden Sie in diesem Artikel .
quelle
Was Sie tun, löst eine Ausnahme aus (und das zu Recht).
Das kannst du immer tun
Aber ich würde nicht an Ihren Anwendungsfall denken.
Warum greifen Sie auf Daten zu, 6 Ebenen verschachtelt, die Sie nicht kennen? Welcher Anwendungsfall rechtfertigt dies?
Normalerweise möchten Sie tatsächlich überprüfen, um welche Art von Objekt es sich handelt.
Außerdem sollten Sie keine Randanweisungen wie verwenden,
if(a.b)
da sie false zurückgeben, wenn ab 0 ist oder sogar wenn sie "0" ist. Überprüfen Sie stattdessen, oba.b !== undefined
quelle
typeof a.b === "undefined" && a.b!=null
- unnötig, den zweiten Teil nach dem ersten zu tun, und es ist sinnvoller, nur zu tunif ("b" in a)
typeof a.b !
== "undefiniert" && ab! = Null` wollen - beachten Sie die!==
Wenn ich Ihre Frage richtig verstehe, möchten Sie am sichersten feststellen, ob ein Objekt eine Eigenschaft enthält.
Am einfachsten ist es, den
in
Operator zu verwenden .Natürlich können Sie dies so tief verschachteln, wie Sie möchten
Ich bin mir nicht sicher, ob dies hilft.
quelle
window.b
undefiniert ist? Sie erhalten einen Tippfehler:Cannot use 'in' operator to search for 'c' in undefined
Wenn Sie lodash verwenden , können Sie deren "has" -Funktion verwenden. Es ähnelt dem nativen "in", erlaubt jedoch Pfade.
quelle
_.get()
mit Standard für einfaches Lesen verwenden:_.get(object, 'a.b.c', 'default');
Versuche dies. Wenn
a.b
undefiniert, wird dieif
Anweisung ausnahmslos verlassen.quelle
Dies ist ein häufiges Problem bei der Arbeit mit tiefen oder komplexen JSON-Objekten. Daher versuche ich zu vermeiden, mehrere Prüfungen zu versuchen / abzufangen oder einzubetten, die den Code unlesbar machen würden. Normalerweise verwende ich diesen kleinen Code in meinem gesamten Verfahren, um die Arbeit zu erledigen.
quelle
Wenn Sie lodash haben, können Sie seine
.get
Methode verwendenoder geben Sie einen Standardwert ein
quelle
Ich benutze undefsafe religiös. Es testet jede Ebene in Ihrem Objekt, bis es entweder den gewünschten Wert erhält oder "undefiniert" zurückgibt. Aber niemals Fehler.
quelle
_.get
Wenn Sie Babel verwenden, können Sie die optionale Verkettungssyntax bereits mit dem Babel-Plugin @ babel / plugin-comment-optional-chaining verwenden . Dies würde es Ihnen ermöglichen, dies zu ersetzen:
mit diesem:
quelle
Ich mag die Antwort von Cao Shouguang, aber ich mag es nicht, bei jedem Aufruf eine Funktion als Parameter an die getSafe-Funktion zu übergeben. Ich habe die Funktion getSafe geändert, um einfache Parameter und reines ES5 zu akzeptieren.
quelle
getSafe(myObj.x.c)
. Versuchte neueste Versionen von Chrome und Firefox.In der Antwort von str wird der Wert 'undefined' anstelle des festgelegten Standardwerts zurückgegeben, wenn die Eigenschaft undefined ist. Dies kann manchmal zu Fehlern führen. Im Folgenden wird sichergestellt, dass die defaultVal immer zurückgegeben wird, wenn entweder die Eigenschaft oder das Objekt undefiniert ist.
quelle
Lodash verfügt über eine
get
Methode, die einen Standard als optionalen dritten Parameter zulässt, wie unten gezeigt:quelle
Stellen Sie sich vor, wir möchten eine Reihe von Funktionen
x
genau dann anwenden, wenn siex
nicht null sind:Nehmen wir nun an, wir müssen dasselbe tun, um
y
:Und das gleiche zu
z
:Wie Sie ohne eine ordnungsgemäße Abstraktion sehen können, werden wir am Ende immer wieder Code duplizieren. Eine solche Abstraktion existiert bereits: die Vielleicht- Monade.
Die Vielleicht- Monade enthält sowohl einen Wert als auch einen rechnerischen Kontext:
Eine naive Implementierung würde folgendermaßen aussehen:
⚠️ Diese Implementierung dient nur zu Illustrationszwecken! Dies sollte nicht so gemacht werden und ist auf vielen Ebenen falsch. Dies sollte Ihnen jedoch eine bessere Vorstellung davon geben, wovon ich spreche.
Wie Sie sehen, kann nichts brechen:
Anhang 1
Ich kann nicht erklären, was Monaden sind, da dies nicht der Zweck dieses Beitrags ist und es Leute gibt, die dies besser können als ich. Wie Eric Elliot jedoch in seinem Blog-Beitrag sagte, wurden JavaScript-Monaden leicht gemacht :
Anlage 2
Hier ist, wie ich Ihr Problem mit dem lösen würde Vielleicht- Monade vonmonetjs
quelle
Ich habe das schon einmal beantwortet und heute zufällig eine ähnliche Überprüfung durchgeführt. Eine Vereinfachung, um zu überprüfen, ob eine verschachtelte gepunktete Eigenschaft vorhanden ist. Sie können dies ändern, um den Wert zurückzugeben, oder einen Standardwert, um Ihr Ziel zu erreichen.
In Ihrer Frage könnten Sie etwas tun wie:
quelle
Ich benutze normalerweise so:
quelle