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

Brian Litzinger
źródło
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.

Matt
źródło
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(...).

ramin
źródło
Ś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 :)

Asaf Lopez
źródło
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);
Upić się
źródło
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);
Lai Xue
źródło
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.

rolinger
źródło
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 ...

Jette
źródło
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);
makkasi
źródło
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.

MTZ
źródło
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...
user_CC
źródło
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.

Karthikeyan M.
źródło
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.

Mike Rizzo
źródło
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

});
Lefan
źródło
2

jeśli używasz TYPESCRIPTi / lub ANGULARmoże to być to!

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

ustawiając typ odpowiedzi na jakąkolwiek naprawioną ten problem, nie mogłem uzyskać dostępu do właściwości odpowiedzi, dopóki nie ustawię res: any

zobacz to pytanie Właściwość „_body” nie istnieje dla typu „Odpowiedź”

rosyjskie lato
źródło
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
});
Tushar Shukla
źródło
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.

rey_coder
źródło
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.

Mohamed Hassan Kadri
źródło
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()
remidej
źródło
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.

Marcus Downing
źródł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);
    }
});
Mariyo
źródło
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”.

emote_control
źródło
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.

KOŁO ZĘBATE
źródło
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)
Ilja Kartašov
źródło
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 );
anakampesan
źródło
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);
Zapnologica
źródło
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.

Efiwe
źródło