Wie kann ich den Fehler „Eigenschaft von undefinierten Objekten kann nicht gelesen werden“ vermeiden?
Lesezeit: 6 Minuten
Ari
In meinem Code beschäftige ich mich mit einem Array, das einige Einträge mit vielen ineinander verschachtelten Objekten enthält, andere dagegen nicht. 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"}];
Das bereitet mir Probleme, da ich manchmal das Array durchlaufen muss und die Inkonsistenz mir Fehler wie diese auslöst:
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)}Dies ist jedoch außerordentlich mühsam, wenn bis zu 5 oder 6 Objekte ineinander verschachtelt sind. Gibt es eine andere (einfachere) Möglichkeit, es zu bekommen? nur mach das console.log wenn es existiert, aber ohne einen Fehler auszulösen?
Der Fehler ist wahrscheinlich eine reguläre Javascript-Ausnahme, also versuchen Sie es try..catch Stellungnahme. Allerdings scheint mir ein Array, das äußerst heterogene Elemente enthält, ein Designproblem zu sein.
– Millimoose
8. Februar 2013 um 22:17 Uhr
Wenn Ihre Struktur nicht über alle Elemente hinweg konsistent ist, was ist dann falsch daran, die Existenz zu prüfen? Wirklich, ich würde es verwenden if ("b" in a && "c" in a.b). Es mag „mühsam“ sein, aber das ist es, was man für Inkonsistenz bekommt … normale Logik.
– Ian
8. Februar 2013 um 22:21
Warum sollten Sie auf nicht vorhandene Eigenschaften zugreifen, warum wissen Sie nicht, wie die Objekte aussehen?
– Bergi
8. Februar 2013 um 22:22
Ich kann verstehen, warum jemand nicht möchte, dass ein Fehler alles zum Absturz bringt. Sie können sich nicht immer darauf verlassen, dass die Eigenschaften eines Objekts existieren oder nicht existieren. Wenn Sie über etwas verfügen, das den Fall verarbeiten kann, dass das Objekt fehlerhaft ist, ist Ihr Code viel effizienter und weniger anfällig.
– SSH Dies
9. April 2013 um 20:19 Uhr
Sie werden überrascht sein, wie viele Objekte/Arrays in realen Situationen fehlerhaft sind
– Noch eine Frage
8. September 2017 um 2:42
str
Aktualisieren:
Wenn Sie JavaScript gemäß ECMAScript 2020 oder höher verwenden, siehe optionale Verkettung.
TypeScript hat in der Version Unterstützung für optionale Verkettung hinzugefügt 3.7.
// use it like this
obj?.a?.lot?.of?.properties
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:
function getSafe(fn, defaultVal) {
try {
return fn();
} catch (e) {
return defaultVal;
}
}
// use it like this
console.log(getSafe(() => obj.a.lot.of.properties));
// or add an optional default value
console.log(getSafe(() => obj.a.lot.of.properties, 'nothing'));
Ich liebe es! Das Einzige, was ich hinzufügen würde, ist eine console.warn im Catch, damit Sie über den Fehler Bescheid wissen, er aber weiterhin auftritt.
– Rabbi Shuki Gur
11. Dezember 2018 um 10:31 Uhr
Fangen alle Ausnahmen ohne erneutes Auslösen sind schlechtund die allgemeine Verwendung von Ausnahmen als Teil des erwarteten Ausführungsflusses ist ebenfalls nicht großartig – auch wenn sie in diesem Fall ziemlich gut begrenzt ist.
– Hugo
25. August 2019 um 11:28
Oh Mann, du bist jetzt mein Held!! Try and Catch hat es für mich erledigt, nach all meinen gescheiterten Versuchen mit Object.assign, dem OR-Operator, dem ternären Operator usw. funktioniert nichts, wenn ein undefinierter Fehler vorliegt. Danke schön!!
– Benutzer7622147
11. Februar 2022 um 15:11 Uhr
Benjamin Grünbaum
Was Sie tun, löst eine Ausnahme aus (und das zu Recht). Sie können immer Folgendes tun:
Aber das würde ich nicht tun, sondern an Ihren Anwendungsfall denken.
Warum greifen Sie auf Daten zu, die auf 6 Ebenen verschachtelt sind und mit denen Sie nicht vertraut sind? Welcher Anwendungsfall rechtfertigt dies?
Normalerweise möchten Sie tatsächlich überprüfen, mit welcher Art von Objekt Sie es zu tun haben.
Übrigens sollten Sie auch keine Aussagen wie verwenden if(a.b) weil es false zurückgibt, wenn ab 0 ist oder sogar wenn es „0“ ist. Überprüfen Sie stattdessen, ob a.b !== undefined
In Bezug auf Ihre erste Änderung: Sie ist gerechtfertigt; Ich beschäftige mich mit JSON-strukturierten Datenbankeinträgen, sodass die Objekte mehrere Feldebenen skalieren (z. B. Einträge.Benutzer.Nachrichten.Datum usw., wo nicht in allen Fällen Daten eingegeben wurden).
– Ari
8. Februar 2013 um 22:23
„Es wird true zurückgeben, wenn ab 0 ist“ – nein. typeof a.b === "undefined" && a.b!=null – Es ist unnötig, den zweiten Teil nach dem ersten zu machen, und es ist sinnvoller, ihn einfach zu machen if ("b" in a)
– Ian
8. Februar 2013 um 22:23
@Ian ja, ich habe es offensichtlich andersherum gemeint, es wird false zurückgeben, selbst wenn ab „0“ ist. Schöner Fang
– Benjamin Grünbaum
8. Februar 2013 um 22:24
@BenjaminGruenbaum Hört sich gut an, ich war mir nicht sicher, ob du das meinst. Ich denke auch, dass du es willst typeof a.b !== “undefiniert” && ab!=null` – beachten Sie das !==
– Ian
8. Februar 2013 um 22:26
Wenn Sie sich nicht mit ab && abc && console.log(abc) langweilen möchten, ist dies die einzige Möglichkeit, Unbekannte konsistent zu protokollieren.
– Brian Cray
8. Februar 2013 um 22:31
mattweiß
Wenn ich Ihre Frage richtig verstehe, möchten Sie am sichersten feststellen, ob ein Objekt eine Eigenschaft enthält.
Der einfachste Weg ist die Verwendung von in Operator.
window.a = "aString";
//window should have 'a' property
//lets test if it exists
if ("a" in window){
//true
}
if ("b" in window){
//false
}
Natürlich können Sie dies so tief verschachteln, wie Sie möchten
if ("a" in window.b.c) { }
Ich bin mir nicht sicher, ob das hilft.
Sie können dies nicht sicher so tief verschachteln, wie Sie möchten. Was ist, wenn window.b ist nicht definiert? Sie erhalten einen Typfehler: Cannot use 'in' operator to search for 'c' in undefined
– Trevor
28. August 2017 um 23:34
Sean Chen
Versuche dies. Wenn a.b Ist undefinedes wird das verlassen if Aussage ohne Ausnahme.
if (a.b && a.b.c) {
console.log(a.b.c);
}
tehwalris
Wenn Sie verwenden lodashdu könntest sie benutzen has Funktion. Es ähnelt dem nativen „in“, erlaubt jedoch Pfade.
var testObject = {a: {b: {c: 'walrus'}}};
if(_.has(testObject, 'a.b.c')) {
//Safely access your walrus here
}
Das Beste, wir können es gebrauchen _.get() mit Standardeinstellung zum einfachen Lesen: _.get(object, 'a.b.c', 'default');
Der Fehler ist wahrscheinlich eine reguläre Javascript-Ausnahme, also versuchen Sie es
try..catch
Stellungnahme. Allerdings scheint mir ein Array, das äußerst heterogene Elemente enthält, ein Designproblem zu sein.– Millimoose
8. Februar 2013 um 22:17 Uhr
Wenn Ihre Struktur nicht über alle Elemente hinweg konsistent ist, was ist dann falsch daran, die Existenz zu prüfen? Wirklich, ich würde es verwenden
if ("b" in a && "c" in a.b)
. Es mag „mühsam“ sein, aber das ist es, was man für Inkonsistenz bekommt … normale Logik.– Ian
8. Februar 2013 um 22:21
Warum sollten Sie auf nicht vorhandene Eigenschaften zugreifen, warum wissen Sie nicht, wie die Objekte aussehen?
– Bergi
8. Februar 2013 um 22:22
Ich kann verstehen, warum jemand nicht möchte, dass ein Fehler alles zum Absturz bringt. Sie können sich nicht immer darauf verlassen, dass die Eigenschaften eines Objekts existieren oder nicht existieren. Wenn Sie über etwas verfügen, das den Fall verarbeiten kann, dass das Objekt fehlerhaft ist, ist Ihr Code viel effizienter und weniger anfällig.
– SSH Dies
9. April 2013 um 20:19 Uhr
Sie werden überrascht sein, wie viele Objekte/Arrays in realen Situationen fehlerhaft sind
– Noch eine Frage
8. September 2017 um 2:42