Auf Objekteigenschaften kann nicht zugegriffen werden, obwohl sie in einem Konsolenprotokoll angezeigt werden

329

Unten sehen Sie die Ausgabe dieser beiden Protokolle. Das erste zeigt deutlich das vollständige Objekt mit der Eigenschaft, auf die ich zugreifen möchte, aber in der nächsten Codezeile kann ich nicht darauf zugreifen config.col_id_3(siehe "undefiniert" im Screenshot?). Kann jemand das erklären? Ich kann Zugang zu jeder anderen Immobilie bekommen, außer field_id_4auch.

console.log(config);
console.log(config.col_id_3);

Dies ist, was diese Zeilen in der Konsole drucken

Konsolenausgabe

Brian Litzinger
quelle
6
können Sie versuchen, und console.log(JSON.stringify(config));teilen Sie die o / p
Arun P Johny
2
Versuchen Sie dies auch, wenn dies funktioniert console.log (config ['col_id_3']);
Zzlalani
5
das hat bei mir funktioniert. Verwenden einer stringifizierten Ausgabe als neue Eingabe für ein Arbeitsobjekt: JSON.parse (JSON.stringify (obj))
Tope
2
Das Stringifizieren und anschließende Parsen hat das Problem aus irgendeinem Grund für mich nicht gelöst. Das Parsen war jedoch völlig erfolgreich. JSON.parse(obj)
JacobPariseau
3
Aus irgendeinem Grund erklären alle Antworten, wie man das Objekt ohne den Schlüssel protokolliert, nicht wie man auf den Schlüssel
zugreift

Antworten:

296

Die Ausgabe von console.log(anObject)ist irreführend; Der Status des angezeigten Objekts wird nur aufgelöst, wenn Sie das >in der Konsole erweitern. Es ist nicht der Zustand des Objekts, wenn Sie console.logdas Objekt haben.

Versuchen Sie es stattdessen console.log(Object.keys(config))oder sogar console.log(JSON.stringify(config))und Sie sehen die Schlüssel oder den Status des Objekts zum Zeitpunkt Ihres Aufrufs console.log.

Sie werden (normalerweise) feststellen, dass die Schlüssel nach Ihrem console.logAnruf hinzugefügt werden .

Matt
quelle
11
Ist dieses Verhalten ein Fehler oder eine Funktion? Wenn es sich um eine Funktion handelt, welche Gründe stecken dahinter?
ESR
2
Wie kommt man dann darum herum? Das Festlegen einer Zeitüberschreitung scheint KEINE gute Lösung zu sein.
Sahand
9
Wie können wir dann vom Objekt aus auf diese Eigenschaft zugreifen?
Rohit Sharma
>Unterscheidet sich das Verhalten der Schaltfläche zur Verdeutlichung davon, ob ein Array oder ein Objekt erweitert wird?
Flimm
Bei einigen Tests ist dieses Problem anscheinend auch bei einem Array aufgetreten. Daher würde ich empfehlen, stattdessen JSON.stringify auszuführen.
Flimm
61

Ich hatte gerade dieses Problem mit einem Dokument, das mit Mongoose aus MongoDB geladen wurde .

Bei der Ausführung console.log()für das gesamte Objekt werden alle Dokumentfelder (wie in der Datenbank gespeichert) angezeigt. Einige einzelne Immobilien-Accessoren würden jedoch zurückkehren undefined, wenn andere (einschließlich _id) gut funktionierten.

Es stellte sich heraus , dass Eigenschaftenaccessoren nur für diese Felder arbeitet in meiner angegebenen mongoose.Schema(...)Definition, während console.log()und JSON.stringify()gibt alle Felder in der db gespeichert.

Lösung (wenn Sie Mongoose verwenden) : Stellen Sie sicher, dass alle Ihre Datenbankfelder in definiert sind mongoose.Schema(...).

ramin
quelle
Ich dachte, Mongoose würde es mir ermöglichen, den JSON ohne Schema (in einem externen Skript) abzufragen, aber Schreibvorgänge verhindern. Es scheint zu funktionieren, weil die _id vorhanden ist und die console.log sagt, dass auf alles andere zugegriffen werden sollte, aber nicht. Bizarr.
Star
6
Es stellte sich heraus, dass ich dies gesehen habe, weil JSON.stringify()(und Knoten console.log()) ihr Verhalten ändern, wenn das angegebene Objekt eine .toJSON()Funktion hat. Die Ausgabe, die Sie sehen, gibt .toJSON()zurück und nicht das ursprüngliche Objekt. Mit Mongoose erhalten Sie Modellobjekte mit einem .toJSON(), das das zugrunde liegende Datenbankobjekt angibt. Das Modellobjekt verfügt nur über Zugriffsmethoden für Felder, die Sie im Schema definieren. Anschließend werden jedoch alle Datenbankfelder angezeigt, wenn Sie es protokollieren, da das zugrunde liegende Objekt tatsächlich von zurückgegeben wird .toJSON().
Ramin
Warum erlaubt Mungo nicht, andere Eigenschaften zu lesen? Haben Sie eine Idee?
Kannan T
Dies war hilfreich für mich beim Hochladen einer CSV in mongodb und beim Abrufen der Eigenschaft. Stellen Sie sicher, dass Ihre Namen übereinstimmen. Tolle Antwort, danke.
9BallOnTheSnap
1
Danke dafür. Ich wurde verrückt, als ich es in der Konsole sah und nicht darauf zugreifen konnte. Der Wert wurde zu meinem Schema hinzugefügt und ich kann loslegen. Danke noch einmal!
Alittletf
27

Überprüfen Sie, ob sich im Objekt ein Array von Objekten befindet. Ich hatte ein ähnliches Problem mit einem JSON:

    "terms": {
        "category": [
            {
                "ID": 4,
                "name": "Cirugia",
                "slug": "cirugia",
                "description": "",
                "taxonomy": "category",
                "parent": null,
                "count": 68,
                "link": "http://distritocuatro.mx/enarm/category/cirugia/"
            }
        ]
    }

Ich habe versucht, über 'Kategorie' auf den Schlüssel 'Name' zuzugreifen, und habe den undefinierten Fehler erhalten, weil ich Folgendes verwendet habe:

var_name = obj_array.terms.category.name

Dann wurde mir klar, dass es eckige Klammern hat, was bedeutet, dass es ein Array von Objekten innerhalb des Kategorieschlüssels enthält, da es mehr als ein Kategorieobjekt haben kann. Um den 'Name'-Schlüssel zu erhalten, habe ich Folgendes verwendet:

var_name = obj_array.terms.category[0].name

Und das macht den Trick.

Vielleicht ist es zu spät für diese Antwort, aber ich hoffe, dass jemand mit dem gleichen Problem dies findet wie ich, bevor er die Lösung gefunden hat :)

Asaf Lopez
quelle
23

Ich hatte das gleiche Problem. Die Lösung für mich bestand darin, die stringifizierte Ausgabe als Eingabe für das Parsen des JSON zu verwenden. das hat bei mir funktioniert. Ich hoffe, es ist nützlich für Sie

var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
Tope
quelle
2
Ja, es hat funktioniert, aber warum ist das erforderlich? Ich habe bereits einen JSON, warum muss ich das tun?
Jain
@dilpeshjain Ich bin mir nicht ganz sicher, aber ich würde es wagen, dass wir JSON noch nicht haben (vielleicht gibt es ein Szenario mit verzögertem Laden, ich bin im Moment nicht gut genug darüber informiert), aber ich gebe alles weiter, was wir haben In JSON.stringify muss eine Zeichenfolge zurückgegeben werden (wie der Aufruf von console.log zum Drucken). Da ich weiß, dass ich zumindest eine Zeichenfolge erhalten kann, kann ich diese Zeichenfolge verwenden, um sofort ein JSON-Objekt zu erstellen.
Tope
4
@jain Sie brauchen dies, weil Javascript eine schreckliche Sprache ist
22

Die Eigenschaft, auf die Sie zugreifen möchten, ist möglicherweise noch nicht vorhanden. Console.log funktioniert, weil es nach einer kleinen Verzögerung ausgeführt wird, aber das ist für den Rest Ihres Codes nicht der Fall. Versuche dies:

var a = config.col_id_3;    //undefined

setTimeout(function()
{
    var a = config.col_id_3;    //voila!

}, 100);
Lai Xue
quelle
1
Ich habe die Methode geladen, um meine Objektwerte zu erhalten. Aber beim ersten Mal bin ich immer noch undefiniert. Diese Sprache macht mich Tag für Tag tot
Teoman Tıngır
Eine einfache Lösung wäre die Implementierung eines Watcher-Versprechens, das prüft, ob die gewünschte Eigenschaft mit setTimeout definiert ist, und das Timeout auflöst + löscht, sobald die Eigenschaft verfügbar ist.
Lai Xue
Beeindruckend. In meinen rund 15 Jahren Webprogrammierung war ich noch nie darauf gestoßen und habe nie darüber nachgedacht, wie das Konsolenprotokoll funktioniert. Ihre Antwort hat dazu beigetragen, einiges davon zu klären.
Kai Qing
12

In meinem Fall habe ich ein Objekt an ein Versprechen übergeben, innerhalb des Versprechens habe ich dem Objekt weitere Schlüssel / Werte hinzugefügt, und als es fertig war, hat das Versprechen das Objekt zurückgegeben.

Ein kleiner Blick von meiner Seite, das Versprechen war jedoch, das Objekt zurückzugeben, bevor es vollständig fertig war ... daher versuchte der Rest meines Codes, das aktualisierte Objekt zu verarbeiten, und die Daten waren noch nicht da. Aber wie oben in der Konsole sah ich das Objekt vollständig aktualisiert, konnte aber nicht auf die Schlüssel zugreifen - sie kamen undefiniert zurück. Bis ich das gesehen habe:

console.log(obj) ;
console.log(obj.newKey1) ;

// returned in console
> Object { origKey1: "blah", origKey2: "blah blah"} [i]
    origKey1: "blah"
    origKey2: "blah blah"
    newKey1: "this info"
    newKey2: "that info"
    newKey3: " more info"
> *undefined*

Das [i] ist ein kleines Symbol, als ich darüber schwebte, hieß es Object value at left was snapshotted when logged, value below was evaluated just now. Dann kam mir der Gedanke, dass mein Objekt bewertet wurde, bevor das Versprechen es vollständig aktualisiert hatte.

rolinger
quelle
10

Ich hatte heute mit diesem Problem zu kämpfen und dachte, ich werde eine Antwort mit meiner Lösung hinterlassen.

Ich habe ein Datenobjekt über Ajax abgerufen, ungefähr so: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Angenommen, dieses Objekt befindet sich in einer Variablen namens data. Wann immer ich data.i18nmich bezog, bekam ich undefined.

  1. console.log(data) zeigte das Objekt wie erwartet
  2. console.log(Object.keys(data))sagte ["constants","i18n"]wie erwartet
  3. Das Umbenennen von i18n in inter hat nichts geändert
  4. Ich habe sogar versucht, die Daten zu wechseln, um "i18n" zum ersten Objekt zu machen
  5. Der Code wurde verschoben, um sicherzustellen, dass das Objekt vollständig festgelegt wurde und es kein Problem mit dem Ajax-Versprechen gab.

Nichts hat geholfen ... Dann habe ich auf der Serverseite die Daten in das PHP-Protokoll geschrieben und es hat Folgendes enthüllt:

{"constants": {"value1":"x","value2":"y"},"\u045618n" {"data1":"x", "data2":"y"}}

Das "i" im Indexschlüssel war eigentlich ein u0456 (kyrillisches i). Dies war in meinem PHP-Editor oder im Browser-Konsolenprotokoll nicht sichtbar. Nur das PHP-Protokoll enthüllte dies ... Das war eine schwierige Frage ...

Jette
quelle
1
Dies war auch mein Problem; hatte in einigen Fällen stattdessen ein kyrillisches 'c'-Zeichen. Ich habe es gefunden, indem ich meine Datei nach der erwarteten Zeichenfolge durchsucht habe. Der Verdächtige wurde nicht ausgewählt, so dass ich wusste, dass es einen falschen Charakter gab, der für das Auge unsichtbar war.
Ritter
Diese Antwort hat mir tatsächlich geholfen, meine Lösung zu finden. Mein Problem war, dass ich meinen Variablennamen falsch geschrieben hatte. Ich habe "udpate" statt "update" gemacht lol
Savlon
8

Meine Daten waren nur JSON-Datenzeichenfolgen. (Diese Variable wurde in der Sitzung als JSON-Zeichenfolge gespeichert.)

console.log(json_string_object)

-> gibt nur die Darstellung dieser Zeichenfolge zurück und es gibt keine Möglichkeit, einen Unterschied zu machen, ob es sich um eine Zeichenfolge oder ein Objekt handelt.

Damit es funktioniert, musste ich es nur wieder in ein reales Objekt konvertieren:

object = JSON.parse(json_string_object);
makkasi
quelle
Dies war die einzige Antwort, die für mich funktioniert hat und wird auch in den Kommentaren der ursprünglichen Frage erwähnt, diese sollte höher sein.
abagh0703
5

2018 warnt uns Mozilla hier in den Mozilla Docs !

Ich zitiere "Logging Objects" :

Nicht benutzen console.log(obj);, benutzen console.log(JSON.parse(JSON.stringify(obj)));.

Auf diese Weise können Sie sicher sein, dass Sie den Wert von obj zum Zeitpunkt der Protokollierung sehen.

MTZ
quelle
4

Dies könnte jemandem helfen, da ich ein ähnliches Problem hatte, bei dem JSON.parse () ein Objekt zurückgab, das ich auf console.log () drucken konnte, aber nicht auf die spezifischen Felder zugreifen konnte und keine der oben genannten Lösungen funktionierte mir. Wie bei der Kombination von JSON.parse () mit JSON.stringify ().

var jsonObj = JSON.parse(JSON.stringify(responseText))

// where responseText is a JSON String returned by the server.

console.log(jsonObj) ///Was printing the object correctly
console.log(jsonObj.Body) /// Was printing Undefined  

Am Ende löste ich das Problem mit einem anderen Parser, der von ExtJs Ext.decode () bereitgestellt wurde.

var jsonObj = Ext.decode(responseText)
console.log(jsonObj.Body) //Worked...
user_CC
quelle
2

In meinem Fall ist es einfach so, dass ich die Daten im Format eines modellähnlichen myMethod(data:MyModelClass) Objekts erhalte, bis das empfangene Objekt vom Typ string war. Welches ist y in console.log (Daten) Ich bekomme den Inhalt. Die Lösung besteht darin, nur den JSON zu analysieren (in meinem Fall).

const model:MyMOdelClass=JSON.parse(data);

Gedanken können nützlich sein.

Karthikeyan M.
quelle
2

Ich bin gerade auf dieses Problem bei Objekten gestoßen, die von csv-parser aus einer CSV-Datei generiert wurden, die von MS Excel generiert wurde. Ich konnte auf alle Eigenschaften mit Ausnahme der ersten Eigenschaft zugreifen - aber es würde in Ordnung sein, wenn ich das gesamte Objekt mit console.log schreiben würde.

Es stellte sich heraus, dass das UTF-8-CSV-Format am Anfang 3 Bytes (ef bb bf) einfügt, die einem unsichtbaren Zeichen entsprechen - die vom csv-Parser als Teil des ersten Eigenschaftskopfs aufgenommen wurden. Die Lösung bestand darin, die CSV mit der Nicht-UTF-Option neu zu generieren, wodurch das unsichtbare Zeichen beseitigt wurde.

Mike Rizzo
quelle
Du bist ein Held! Vielen Dank für die Veröffentlichung. Ich zog mir die Haare aus.
Jordan S
Nochmals vielen Dank für die Veröffentlichung! Rettete meine Nacht!
Oliver Hickman
2

Ich hatte ein ähnliches Problem, hoffe, die folgende Lösung hilft jemandem.
Sie können verwendensetTimeout Funktion verwenden, wie einige Leute hier vorschlagen, aber Sie wissen nie, wie lange Ihr Browser benötigt, um Ihr Objekt zu definieren.

Aus diesem Grund würde ich vorschlagen, setIntervalstattdessen die Funktion zu verwenden. Es wird warten, bis Ihr Objekt config.col_id_3definiert ist, und dann Ihren nächsten Codeteil auslösen, der Ihre spezifischen Objekteigenschaften erfordert.

window.addEventListener('load', function(){

    var fileInterval = setInterval(function() {
        if (typeof config.col_id_3 !== 'undefined') {

            // do your stuff here

            clearInterval(fileInterval); // clear interval
        }
    }, 100); // check every 100ms

});
Lefan
quelle
2

Wenn Sie TYPESCRIPTund / oder verwenden ANGULAR, könnte es dies sein!

.then((res: any) => res.json())

Wenn ich den Antworttyp auf ein für mich behobenes Problem setze, konnte ich nicht auf Eigenschaften der Antwort zugreifen, bis ich res: any festgelegt habe

siehe diese Frage Die Eigenschaft '_body' ist für den Typ 'Response' nicht vorhanden.

russiansummer
quelle
1

Ich hatte das gleiche Problem und keine der oben genannten Lösungen funktionierte für mich und es fühlte sich danach wie eine Vermutung an. Das Umschließen meines Codes, der das Objekt in eine setTimeoutFunktion erstellt, hat mir jedoch geholfen.

setTimeout(function() {
   var myObj = xyz; //some code for creation of complex object like above
   console.log(myObj); // this works
   console.log(myObj.propertyName); // this works too
});
Tushar Shukla
quelle
1

Ich hatte ein ähnliches Problem oder war vielleicht nur verwandt.

In meinem Fall habe ich auf Eigenschaften eines Objekts zugegriffen, aber eines war undefiniert. Ich stellte fest, dass das Problem ein Leerzeichen im serverseitigen Code beim Erstellen des Schlüssels val des Objekts war.

Mein Ansatz war wie folgt ...

Mein Objekt erstellen ... Beachten Sie den Leerraum in "Wort"

Antwort bekomme ich von meiner REST-API

Javascript-Code zum Protokollieren der Werte

Protokollergebnisse von der Konsole

Nachdem ich den Leerraum aus dem serverseitigen Code entfernt hatte, mit dem das Objekt erstellt wurde, konnte ich nun wie folgt auf die Eigenschaft zugreifen ...

Ergebnis nach dem Entfernen von Leerzeichen

Dies ist möglicherweise nicht das Problem mit dem Fall der betreffenden Frage, war jedoch für meinen Fall und möglicherweise für einen anderen. Ich hoffe es hilft.

rey_coder
quelle
1

Ich hatte gerade das gleiche Problem mit einem Dokument, das mit Mongoose aus MongoDB geladen wurde.

Es stellte sich heraus, dass ich die Eigenschaft verwende find(), um nur ein Objekt zurückzugeben, also wechselte ich find()zu findOne()und alles funktionierte für mich.

Lösung (wenn Sie Mongoose verwenden): Stellen Sie sicher, dass Sie nur ein Objekt zurückgeben, damit Sie es analysieren können. Andernfalls object.idwird es als Array behandelt, sodass Sie darauf zugreifen müssen object[0].id.

Mohamed Hassan Kadri
quelle
1

Für mich stellte sich heraus, dass es sich um ein Mungo-Problem handelte.

Ich habe Objekte durchlaufen, die ich aus einer Mongo-Abfrage erhalten habe. Ich musste nur entfernen:

items = await Model.find()

Und ersetzen Sie es durch:

items = await Model.find().lean()
remidej
quelle
0

Ich hatte ein Problem wie dieses und fand, dass die Lösung mit Underscore.js zu tun hatte. Meine anfängliche Protokollierung ergab keinen Sinn:

console.log(JSON.stringify(obj, null, 2));

> {
>   "code": "foo"
> }

console.log(obj.code);

> undefined

Ich fand die Lösung, indem ich auch die Schlüssel des Objekts betrachtete:

console.log(JSON.stringify(Object.keys(obj)));

> ["_wrapped","_chain"]

Dies führte mich zu der Erkenntnis, dass objes sich tatsächlich um einen Underscore.js-Wrapper um ein Objekt handelte, und das anfängliche Debugging hat mich angelogen.

Marcus Downing
quelle
0

Ich hatte ein ähnliches Problem (bei der Entwicklung für SugarCRM), bei dem ich anfange:

var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});

// This should load object with attributes 
leadBean.fetch();

// Here were my attributes filled in with proper values including name
console.log(leadBean);

// Printed "undefined"
console.log(leadBean.attributes.name);

Das Problem war fetch(), es war ein asynchroner Aufruf, also musste ich meinen Code umschreiben in:

var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});

// This should load object with attributes 
leadBean.fetch({
    success: function (lead) {
        // Printed my value correctly
        console.log(lead.attributes.name);
    }
});
Mariyo
quelle
0

Nur für den Fall, dass dies für jemanden hilfreich ist, hatte ich ein ähnliches Problem, und das liegt daran, dass jemand in dem Objekt, mit dem ich gearbeitet habe, eine Überschreibung für .toJSON erstellt hat. Das Objekt war also so etwas wie:

{
  foo: {
         bar: "Hello"
         baz: "World"
       }
}

Aber .toJSON () war:

toJSON() {
  return this.foo
}

Als ich JSON.stringify (myObject) aufrief, gab es "{" bar ":" Hello "," baz ":" World "}" zurück. Object.keys (myObject) enthüllte jedoch das "foo".

emote_control
quelle
toJson()Dies ist der Punkt, den hier niemand erwähnt hat. Ich weiß nicht, warum diese Antwort abgelehnt wurde, da dies eine Möglichkeit ist, ein Objekt zu erstellen, das einen anderen Wert als die JSON- oder Konsolendarstellung hat. Ich wusste nicht, dass es existiert, bis ich es in einer anderen Antwort aufgedeckt habe, und ich denke, diese Antwort sollte positiv bewertet werden, da es ein Punkt ist, den man bei solchen Problemen berücksichtigen sollte.
Rick Love
In Anbetracht der Anzahl der Antworten mit genau 0 Punkten denke ich, dass jemand einfach alles heruntergestimmt hat.
emote_control
0

Ich hatte heute das gleiche Problem. In meinem Fall waren die Schlüssel verschachtelt, dh key1.key2. Ich habe die Schlüssel mit split () geteilt und dann die eckige Klammer-Notation verwendet, die für mich funktioniert hat.

var data = {
    key1: {
          key2: "some value"
       }
}

Ich teilte die Schlüssel und benutzte sie so, Daten [Schlüssel1] [Schlüssel2], die die Arbeit für mich erledigten.

ZAHN
quelle
0

Ich hatte heute das gleiche Problem. Problem wurde durch uglify-js verursacht. Nachdem ich das gleiche nicht hässliche Code-Problem ausgeführt hatte, wurde es gelöst. Entfernen von

--mangle-props

von uglify-js war genug, um uglifizierten Code zu haben.

Möglicherweise empfiehlt es sich, ein Präfix für Eigenschaften zu verwenden, die mit der Regex-Regel für uglify-js entstellt werden müssen.

Hier ist die Quelle:

var data = JSON.parse( content);
...
this.pageIndex = parseInt(data.index);
this.pageTotal = parseInt(data.total);
this.pageLimit = parseInt(data.limit); 

und so wurde es hässlich gemacht:

var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)
Ilja Kartašov
quelle
0

Keiner der JSON-Stringify / Parse hat für mich funktioniert.

formValues.myKey:               undefined
formValues.myKey with timeout:  content

Ich wollte den Wert von formValues.myKeyund was der Trick tat, war ein setTimeout 0 wie im folgenden Beispiel. Ich hoffe es hilft.

console.log('formValues.myKey: ',formValues.myKey);
setTimeout( () => { 
  console.log('formValues.myKey with timeout: ', formValues.myKey);
}, 0 );
Anacampesan
quelle
0

Ich bin gerade auch auf dieses Problem gestoßen, und kurz gesagt, meine API hat einen Zeichenfolgentyp und nicht JSON zurückgegeben. Es sah also genauso aus, als Sie es in das Protokoll druckten, aber wenn ich versuchte, auf die Eigenschaften zuzugreifen, gab es einen undefinierten Fehler.

API-Code:

     var response = JsonConvert.DeserializeObject<StatusResult>(string Of object);
     return Json(response);

vorher war ich gerade zurückgekehrt:

return Json(string Of object);
Zapnologica
quelle