Nie można uzyskać dostępu do właściwości obiektu, nawet jeśli jest ona wyświetlana w dzienniku konsoli


329

Poniżej widać dane wyjściowe z tych dwóch dzienników. Pierwszy wyraźnie pokazuje pełny obiekt z właściwością, do której próbuję uzyskać dostęp, ale w następnym wierszu kodu nie mogę uzyskać do niego dostępu config.col_id_3(patrz „niezdefiniowany” na zrzucie ekranu?). Czy ktoś może to wyjaśnić? Mogę uzyskać dostęp do każdej innej nieruchomości oprócz field_id_4.

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

To właśnie te linie drukują w Konsoli

Wyjście konsoli


6
czy możesz spróbować console.log(JSON.stringify(config));podzielić się o / p
Arun P. Johny

2
spróbuj także tego, jeśli to działa console.log (config ['col_id_3']);
zzlalani

5
to działało dla mnie. z zastosowaniem danych stratyfikowanych jako nowego wejścia dla obiektu roboczego: JSON.parse (JSON.stringify (obj))
Tope

2
Z jakichś powodów rozwarstwienie, a następnie parsowanie nie rozwiązało problemu. Jednak parsowanie wprost tak zrobiło. JSON.parse(obj)
JacobPariseau

3
Z jakiegoś powodu wszystkie odpowiedzi wyjaśniają, jak zalogować obiekt bez klucza, a nie jak uzyskać dostęp do klucza
remidej,

Odpowiedzi:


296

Wyniki console.log(anObject)są mylące; stan wyświetlanego obiektu zostanie rozwiązany dopiero po rozwinięciu >konsoli. To nie jest stan obiektu, gdy jesteś console.logobiektem.

Zamiast tego spróbuj console.log(Object.keys(config)), a nawet console.log(JSON.stringify(config))zobaczysz klucze lub stan obiektu w momencie, w którym zadzwoniłeś console.log.

Zazwyczaj zauważysz, że klucze są dodawane po zakończeniu console.logpołączenia.


11
Czy to zachowanie jest błędem czy cechą? Jeśli jest to funkcja, jakie jest jej uzasadnienie?
ESR

2
Jak można to obejść? Ustawienie limitu czasu NIE wydaje się dobrym rozwiązaniem.
Sahand

9
Jak więc uzyskać dostęp do tej właściwości z obiektu?
Rohit Sharma

Aby wyjaśnić, czy zachowanie >przycisku różni się w zależności od tego, czy tablica jest rozwijana, czy obiekt?
Flimm,

Po przeprowadzeniu niektórych testów wydaje się, że napotkałeś ten problem nawet z tablicą, więc zamiast tego poleciłbym wykonanie pliku JSON.stringify.
Flimm,

62

Właśnie miałem ten problem z dokumentem załadowanym z MongoDB przy użyciu Mongoose .

Podczas działania console.log()na całym obiekcie pojawią się wszystkie pola dokumentu (zapisane w bazie danych). Jednak niektóre osoby przystępujące do nieruchomości wrócą undefined, gdy inne (w tym_id ) działali dobrze.

Okazało się, że akcesory własności działają tylko dla tych pól określonych w mojej mongoose.Schema(...)definicji, natomiast console.log()iJSON.stringify() zwrotów wszystkie pola przechowywane w db.

Rozwiązanie (jeśli używasz Mongoose) : upewnij się, że wszystkie pola db są zdefiniowane w mongoose.Schema(...).


Świetne wyjaśnienie tego problemu, pomyślałem, że Mongoose pozwoli mi zapytać json bez schematu (w zewnętrznym skrypcie), ale uniemożliwi zapis. Wygląda na to, że działa, ponieważ _id jest obecny, a console.log mówi, że wszystko inne powinno być dostępne, ale nie jest. Dziwaczny.
bstar

7
Okazuje się, że widziałem to, ponieważ JSON.stringify()(i Węzły console.log()) zmieniają swoje zachowanie, jeśli dany obiekt ma .toJSON()funkcję. Wyświetlane dane wyjściowe .toJSON()zwracają, a nie oryginalny obiekt. Mongoose daje obiekty modelowe, .toJSON()które dają bazowy obiekt db. Obiekt modelu ma tylko akcesoria dla pól zdefiniowanych w schemacie, ale wtedy wszystkie pola db pojawiają się po zalogowaniu, ponieważ faktycznie widzisz zwracany obiekt .toJSON().
ramin

Dlaczego mangusta nie pozwala na odczytanie innych właściwości, masz jakiś pomysł?
Kannan T

Pomogło mi to podczas przesyłania pliku CSV do mongodb i pobierania właściwości. Upewnij się, że twoje nazwiska pasują. Świetna odpowiedź, dziękuję.
9BallOnTheSnap

1
Dziękuję Ci za to. Oszalałem, widząc to w konsoli i nie mogąc uzyskać do niego dostępu. Dodałem wartość do mojego schematu i jestem gotowy, aby przejść. Dzięki jeszcze raz!
alittletf

27

Sprawdź, czy wewnątrz obiektu znajduje się tablica obiektów. Miałem podobny problem z JSON:

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

Próbowałem uzyskać dostęp do klucza „nazwa” z „kategorii” i otrzymałem niezdefiniowany błąd, ponieważ korzystałem z:

var_name = obj_array.terms.category.name

Potem zdałem sobie sprawę, że ma nawiasy kwadratowe, co oznacza, że ​​ma tablicę obiektów wewnątrz klucza kategorii, ponieważ może mieć więcej niż jeden obiekt kategorii. Tak więc, aby uzyskać klucz „nazwa” użyłem tego:

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

I to załatwia sprawę.

Być może jest już za późno na tę odpowiedź, ale mam nadzieję, że ktoś z tym samym problemem znajdzie to, co przedtem, zanim znalazł rozwiązanie :)


23

Miałem ten sam problem. Rozwiązaniem dla mnie było użycie wyjściowego łańcucha jako danych wejściowych do parsowania JSON. to działało dla mnie. mam nadzieję, że ci się przyda

var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);

2
Tak, zadziałało, ale dlaczego jest to wymagane? Mam już JSON, dlaczego muszę to zrobić?
jain

@dilpeshjain Nie jestem do końca pewien, ale zaryzykuję, że tak naprawdę nie mamy już JSON (być może istnieje leniwy scenariusz typu ładowania, w tej chwili nie mam wystarczającej wiedzy), ale przekazując wszystko, co mamy do pliku JSON.stringify wymaga zwrócenia ciągu znaków (podobnie jak wywołanie konsoli console.log do drukowania). Ponieważ wiem, że mogę przynajmniej uzyskać ciąg, dzięki temu mogę na pewno utworzyć obiekt JSON od razu.
Tope,

4
@jain potrzebujesz tego, ponieważ javascript jest okropnym językiem

22

Właściwość, do której próbujesz uzyskać dostęp, może jeszcze nie istnieć. Console.log działa, ponieważ uruchamia się z niewielkim opóźnieniem, ale nie dotyczy to reszty kodu. Spróbuj tego:

var a = config.col_id_3;    //undefined

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

}, 100);

1
Użyłem metody onload, aby uzyskać moje wartości obiektów, ale wciąż daje mi niezdefiniowane za pierwszym razem .. Ten język sprawia, że ​​jestem martwy z dnia na dzień
Teoman Tıngır

łatwym rozwiązaniem byłoby zaimplementowanie obietnicy obserwatora, która sprawdza, czy pożądana właściwość jest zdefiniowana za pomocą setTimeout, i rozwiązuje + usuwa limit czasu, gdy właściwość stanie się dostępna.
Lai Xue

Łał. Przez 15 lat programowania nie spotkałem się z tym i nigdy nie zastanawiałem się, jak działa dziennik konsoli. Twoja odpowiedź pomogła ci to wyjaśnić.
Kai Qing

12

W moim przypadku przekazałem obiekt do obietnicy, w ramach obietnicy dodawałem więcej klucza / wartości do obiektu, a kiedy to zostało zrobione, obietnica zwróciła obiekt.

Jednak z mojego drobnego spojrzenia, obietnica zwróciła obiekt, zanim został w pełni ukończony ... tak więc reszta mojego kodu próbowała przetworzyć zaktualizowany obiekt, a danych jeszcze nie było. Ale tak jak powyżej, w konsoli widziałem obiekt w pełni zaktualizowany, ale nie mogłem uzyskać dostępu do klawiszy - wracały niezdefiniowane. Dopóki tego nie zobaczyłem:

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*

[I] jest trochę ikona, kiedy unosił się nad nim powiedziane Object value at left was snapshotted when logged, value below was evaluated just now. Właśnie wtedy przyszło mi do głowy, że mój obiekt jest oceniany, zanim obietnica go w pełni zaktualizuje.


10

Dzisiaj zmagałem się z tym problemem i pomyślałem, że zostawię odpowiedź z moim rozwiązaniem.

Pobierałem obiekt danych przez ajax, coś takiego: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Powiedzmy, że ten obiekt znajduje się w zmiennej o nazwie dane. Ilekroć się odnosiłam data.i18n, dostałam undefined.

  1. console.log(data) pokazał obiekt zgodnie z oczekiwaniami
  2. console.log(Object.keys(data))powiedział ["constants","i18n"]zgodnie z oczekiwaniami
  3. Zmiana nazwy i18n na inter nic nie zmieniła
  4. Próbowałem nawet zmienić dane, aby „i18n” był pierwszym obiektem
  5. Przeniesiłem kod, aby absolutnie upewnić się, że obiekt został całkowicie ustawiony i nie było problemu z obietnicą ajax.

Nic nie pomogło ... Potem po stronie serwera zapisałem dane do dziennika php i ujawniło to:

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

„I” w kluczu indeksu było w rzeczywistości u0456 (cyrylica i). Nie było to widoczne w moim edytorze php ani w dzienniku konsoli przeglądarki. Tylko dziennik php to ujawnił ... To był trudny ...


1
To był również mój problem; zamiast tego miał w niektórych przypadkach postać cyrylicy „c”. Znalazłem go, przeszukując mój plik w poszukiwaniu oczekiwanego ciągu; podejrzany nie został wybrany, więc powiedział mi, że zła postać była niewidoczna dla oka.
rycerz

Ta odpowiedź pomogła mi znaleźć moje rozwiązanie. Mój problem polegał na tym, że źle wpisałem nazwę zmiennej. Zrobiłem „udpate” zamiast „update” lol
Savlon

8

Moje dane były tylko ciągiem danych JSON. (Ta zmienna została zapisana jako ciąg json w sesji).

console.log(json_string_object)

-> zwraca tylko reprezentację tego ciągu i nie ma sposobu, aby zrobić różnicę, czy jest to ciąg, czy obiekt.

Aby więc działało, wystarczyło przekonwertować go z powrotem na prawdziwy obiekt:

object = JSON.parse(json_string_object);

To była jedyna odpowiedź, która zadziałała dla mnie i jest również wspomniana w komentarzach do pierwotnego pytania, powinna być wyższa.
abagh0703

5

W 2018 roku Mozilla ostrzega nas tutaj w Dokumentach Mozilla !

Cytuję „Rejestrowanie obiektów” :

Nie używaj console.log(obj);, używaj console.log(JSON.parse(JSON.stringify(obj)));.

W ten sposób masz pewność, że widzisz wartość obj w momencie jej zalogowania.


4

Może to komuś pomóc, ponieważ miałem podobny problem, w którym JSON.parse () zwracał obiekt, który mogłem wydrukować na console.log (), ale nie mogłem uzyskać dostępu do określonych pól i żadne z powyższych rozwiązań nie działało mnie. Jak użycie kombinacji JSON.parse () z 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  

Skończyło się na rozwiązaniu problemu przy użyciu innego parsera dostarczonego przez ExtJs Ext.decode ();

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

2

W moim przypadku zdarza się tak, że mimo iż otrzymuję dane w formacie myMethod(data:MyModelClass) modelopodobnym, dopóki otrzymany obiekt nie ma typu string. Który jest w pliku console.log (dane) otrzymuję treść. Rozwiązaniem jest po prostu parsowanie JSON (w moim przypadku)

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

Myśl może być przydatna.


2

Właśnie napotkałem ten problem z obiektami wygenerowanymi przez csv-parser z pliku CSV wygenerowanego przez MS Excel. Byłem w stanie uzyskać dostęp do wszystkich właściwości oprócz pierwszej właściwości - ale byłoby dobrze, gdybym napisał cały obiekt za pomocą console.log.

Okazało się, że format UTF-8 CSV wstawia na początku 3 bajty (ef bb bf) odpowiadające niewidocznemu znakowi - które zostały włączone jako część pierwszego nagłówka właściwości przez csv-parser. Rozwiązaniem było ponowne wygenerowanie pliku CSV przy użyciu opcji innej niż UTF, co wyeliminowało niewidoczny charakter.


Jesteś bohaterem! Dzięki za opublikowanie tego. Wyciągałam włosy.
Jordan S

Jeszcze raz dziękuję za opublikowanie tego! Uratowałem moją noc!
Oliver Hickman

2

Mam podobny problem, mam nadzieję, że poniższe rozwiązanie komuś pomoże.
Możesz użyć setTimeoutfunkcji, jak sugerują tutaj niektórzy faceci, ale nigdy nie wiesz, jak dokładnie Twoja przeglądarka musi zdefiniować obiekt.

Poza tym sugerowałbym użycie setIntervalfunkcji zamiast tego. Poczeka, aż obiekt config.col_id_3zostanie zdefiniowany, a następnie uruchomi następną część kodu, która wymaga określonych właściwości obiektu.

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

});


1

Miałem ten sam problem i żadne z powyższych rozwiązań nie zadziałało i wydawało mi się, że potem zgaduję. Jednak owinięcie mojego kodu, który tworzy obiekt w setTimeoutfunkcji, załatwiło sprawę.

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
});

1

Miałem podobny problem, a może po prostu spokrewniony.

W moim przypadku miałem dostęp do właściwości obiektu, ale jeden był niezdefiniowany. Odkryłem, że problemem jest spacja w kodzie po stronie serwera podczas tworzenia klucza, val obiektu.

Moje podejście było następujące ...

tworzenie mojego obiektu ... zwróć uwagę na białą spację w „słowie”

odpowiedź otrzymuję z mojego interfejsu API REST

kod javascript do rejestrowania wartości

zaloguj wyniki z konsoli

Po usunięciu białych znaków z kodu po stronie serwera tworzącego obiekt, mogłem teraz uzyskać dostęp do właściwości jak poniżej ...

wynik po usunięciu białych znaków

To może nie być problem w przypadku pytania przedmiotowego, ale dotyczyło mojego przypadku i może być tak w przypadku innego. Mam nadzieję, że to pomoże.


1

Właśnie miałem ten sam problem z dokumentem załadowanym z MongoDB przy użyciu Mongoose.

Okazało się, że używam właściwość find(), aby powrócić tylko jeden przedmiot, więc zmieniła find()się findOne()i wszystko działało na mnie.

Rozwiązanie (jeśli używasz Mongoose): Upewnij się, że zwrócisz tylko jeden obiekt, abyś mógł go przeanalizować object.idlub będzie traktowany jako tablica, więc musisz uzyskać do niego dostęp w ten sposób object[0].id.


1

Dla mnie okazało się, że jest to problem związany z mangustą.

Zapętlałem obiekty, które otrzymałem z zapytania Mongo. Musiałem tylko usunąć:

items = await Model.find()

I zamień na:

items = await Model.find().lean()

0

Miałem taki problem i znalazłem rozwiązanie związane z Underscore.js. Moje początkowe logowanie nie miało sensu:

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

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

console.log(obj.code);

> undefined

Znalazłem rozwiązanie, patrząc również na klucze obiektu:

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

> ["_wrapped","_chain"]

Doprowadziło mnie to do wniosku, że objtak naprawdę obiekt był opakowaniem Underscore.js wokół obiektu, a początkowe debugowanie mnie okłamało.


0

Miałem podobny problem (podczas programowania dla SugarCRM), gdzie zaczynam od:

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);

Problem polegał na fetch()wywołaniu asynchronicznym, więc musiałem przepisać kod na:

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);
    }
});

0

Na wypadek, gdyby było to komuś pomocne, miałem podobny problem, a to dlatego, że ktoś utworzył przesłonięcie dla .toJSON w obiekcie, z którym pracowałem. Obiekt był więc podobny do:

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

Ale .toJSON () był:

toJSON() {
  return this.foo
}

Kiedy zadzwoniłem do JSON.stringify (myObject), zwróciło „{” bar ”:„ Hello ”,„ baz ”:„ World ”}”. Jednak Object.keys (myObject) ujawnił „foo”.


toJson()o tym nie wspomina nikt. Nie wiem, dlaczego ta odpowiedź została odrzucona, ponieważ jest to sposób na utworzenie obiektu, który ma inną wartość niż reprezentacja json lub konsoli. Nie wiedziałem, że istnieje, dopóki nie odkryłem go w innej odpowiedzi, i uważam, że odpowiedź ta powinna być oceniona pozytywnie, ponieważ warto rozważyć tego rodzaju problemy.
Rick Love

Biorąc pod uwagę liczbę odpowiedzi, które mają dokładnie 0 punktów, myślę, że ktoś właśnie przeszedł głosowanie wszystkiego.
emote_control

0

Dzisiaj stanąłem przed tym samym problemem. W moim przypadku klucze zostały zagnieżdżone, tzn. Key1.key2. Rozdzieliłem klucze za pomocą split (), a następnie użyłem notacji w nawiasach kwadratowych, która zadziałała dla mnie.

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

Rozdzieliłem klucze i użyłem tego w ten sposób, dane [key1] [key2], które wykonały dla mnie zadanie.


0

Miałem dzisiaj ten sam problem. Problem został spowodowany przez uglify-js. Po wykonaniu tego samego nieglikowanego kodu problem został rozwiązany. Usuwanie

--mangle-props

z uglify-js wystarczyło, by mieć działający kod nieoczyszczony.

Być może najlepszą praktyką jest użycie jakiegoś prefiksu dla właściwości, które muszą być zniekształcone za pomocą reguły wyrażenia regularnego dla uglify-js.

Oto źródło:

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

a oto, w jaki sposób został zglikowany:

var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)

0

Żaden z JSON stringify / pars nie działał dla mnie.

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

Chciałem wartość formValues.myKeyi to, co zrobiło lewę, to setTimeout 0, jak w poniższym przykładzie. Mam nadzieję, że to pomoże.

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

0

Właśnie spotkałem ten problem i krótko mówiąc mój interfejs API zwrócił typ ciągu, a nie JSON. Wyglądało to dokładnie tak samo, gdy drukowałeś go w dzienniku, jednak ilekroć próbowałem uzyskać dostęp do właściwości, dawał mi nieokreślony błąd.

Kod API:

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

poprzednio właśnie wracałem:

return Json(string Of object);

0

Miałem podobny problem dzisiaj w React. W końcu zdałem sobie sprawę, że przyczyną problemu był stan, który nie został jeszcze ustawiony. Dzwoniłem user.user.namei chociaż pojawiał się w konsoli, nie mogłem uzyskać dostępu do niego w moim komponencie, dopóki nie dołączyłem sprawdzania, czy user.userzostał ustawiony, a następnie dzwoniłem user.user.name.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.