Waarom is deze objecteigenschap niet gedefinieerd?

Overweeg de onderstaande code. De eerste console.log registreert de afbeelding correct en u kunt de eigenschappen ervan zien in de onderstaande afbeelding. Nochtans, wanneer ik probeer om er een te loggen als het zijn eigenschappen aan de console geeft, krijg ik undefined !

console.log(that.data[0].cards); //works -- see image below
console.log(that.data[0].cards.E); //undefined
console.log(that.data[0].cards['E']); //undefined
console.log(that.data[0].cards.hasOwnProperty('E')); //false

var test = JSON.stringify(that.data[0]);
console.log(test);//{}

for( var key in that.data[0].cards ) {
    console.log('hello????') //doesn't appear in the console
}

console.log( Object.keys( that.data[0].cards ) ); //[]
console.log( that.data[0].cards.propertyIsEnumerable("E") ); //false
console.log( that.data[0].cards.__lookupGetter__( "E" ) ); //undefined

Het resultaat in de console:

enter image description here

Enig idee wat hier aan de hand is? De xml -eigenschap in that.data [0] zou ook eigenschappen moeten bevatten - in feite hetzelfde genoemd als de eigenschappen in -kaarten .

FWIW, ik krijg hetzelfde in Firebug (de afbeelding van de console hierboven is Chrome).

11
JSON.stringify (that) lijkt niets te doen behalve het script volledig stopzetten. Werpt geen fout of iets anders, maar niets wordt uitgevoerd na de aanroep van JSON.stringify (that) . Ik heb mijn vraag bijgewerkt om de resultaten weer te geven van JSON.stringify (that.data [0] .cards) , die het alleen als een leeg object toont {} .
toegevoegd de auteur maxedison, de bron
Ik heb de afbeelding bijgewerkt.
toegevoegd de auteur maxedison, de bron
Weet je zeker dat het object deze keer echt niet leeg is? Je hebt het niet uitgebreid ...
toegevoegd de auteur pimvdb, de bron
Bedankt. Ik kan nog steeds niet reproduceren. Kunt u misschien een vereenvoudigde, geïsoleerde testcase geven op jsfiddle.net ?
toegevoegd de auteur pimvdb, de bron
Kan je niet helpen als we het gedrag niet kunnen repliceren. Kunt u de JSON leveren?
toegevoegd de auteur aziz punjani, de bron
Kun je het resultaat van JSON.stringify (dat) doorgeven?
toegevoegd de auteur FreeCandies, de bron

2 antwoord

Ik heb het probleem opgelost. Kortom, het object in kwestie ( that.data [0] .cards ) heeft zijn eigenschappen gemaakt door een functie a() die wordt uitgevoerd nadat alle AJAX-aanvragen voor de noodzakelijke XML-bestanden zijn verwerkt. Ik sta toe dat de aanvragen asynchroon worden uitgevoerd, met behulp van een teller om in de succes callback-functie te bepalen of a() nog moet worden aangeroepen.

Nadat a() is uitgevoerd, wordt de functie b() uitgevoerd op that.data [i] .cards . b() werd echter uitgevoerd voordat a() werd aangeroepen vanwege de afhankelijkheid van a() op de asynchrone verzoeken. Dus de oplossing was simpelweg om a() call b() te maken.

Dus dit bleek een vrij simpele fout van mijn kant te zijn. Wat het zo verwarrend maakte, was het feit dat het loggen van that.data [0] .cards naar de console me liet zien dat het object kaarten al was gebouwd, het was het nog niet. Dus de console gaf me onjuiste of in ieder geval onduidelijke informatie.

Bedankt voor de hulp van iedereen gisteravond! Upvotes rondom :)

12
toegevoegd
een ander mysterie opgelost :)
toegevoegd de auteur Esailija, de bron
Ik strompelde vandaag hetzelfde probleem aan. Bedankt.
toegevoegd de auteur rr-, de bron

Ik denk dat de objectsleutels niet-afdrukbare tekens hebben, zoals op deze manier kunnen worden gerepliceerd:

var obj = {};
obj["E"+String.fromCharCode(15)] = new Array(15);

console.log(obj);

/*Object
E: Array[15]
__proto__: Object*/

console.log(obj.E)

//undefined

console.log( obj["E"+String.fromCharCode(15)] )

//[]

Bewerken: u kunt zien of dit het geval is voor uw objectsleutels:

var realKeys = [];

for( var key in obj ) {
realKeys.push( [].slice.call( key ).map( function(v){return v.charCodeAt(0);} ).join(" ") );
}

//["69 15"] (69 stands for the letter "E" and 15 was the unprintable character I added manually)

Bewerken 2: Omdat je dat niet kunt, heb ik een andere manier bedacht om te zien of er niet-afdrukbare tekens zijn:

Copypaste de sleutel reeks als volgt: (ga helemaal aan beide kanten zo veel als je kunt, dus je kiest onzichtbare karakters)

Dep je klembord dan als volgt (zorg ervoor dat je dubbele aanhalingstekens gebruikt):

7
toegevoegd
Lijkt hetzelfde resultaat te produceren. Dat deed ik: console.log (that.data [0] .cards ['E' + String.fromCharCode (15)]) & zwnj;;
toegevoegd de auteur maxedison, de bron
JSON.stringify (that.data [0]) produceert: {"session": "01", "xml": {}, "cards": {}} . De waarheid is dat het xml -object ook eigenschappen bevat die in feite hetzelfde zijn als het -kaart -object. Ik heb ook mijn vraag bijgewerkt om de resultaten van de door u voorgestelde voor -koppeling op te nemen, maar deze lijkt niet eens te worden uitgevoerd.
toegevoegd de auteur maxedison, de bron
Ik heb mijn bericht bijgewerkt om het resultaat daarvan weer te geven. Ik kan geen link naar de pagina maken omdat ik de ontwikkeling lokaal doe. Dit is gemakkelijk een van de gekste dingen die ik ooit ben tegengekomen bij het programmeren ...
toegevoegd de auteur maxedison, de bron
Het object wordt dynamisch aangemaakt via AJAX-aanvragen die XML-gegevens laden (met behulp van jQuery). Nadat alle gegevens zijn geladen, wordt deze geparseerd (opnieuw, met behulp van jQuery). Het is op dit punt dat de zogenaamd "undefined" arrays (cards.E, cards.N, card.X) worden gemaakt. Ik zal je laatste bewerking in de ochtend proberen. Bedankt voor je hulp.
toegevoegd de auteur maxedison, de bron
@macedison: En vanwege de reden van @ Esailija, kopieer/plak het exacte resultaat van JSON.stringify (that.data [0]) zodat het kan worden onderzocht
toegevoegd de auteur pimvdb, de bron
Dat komt omdat je object een ander onzichtbaar karakter kan hebben dan String.fromCharCode (15) , het kan 3, 24 of 22 zijn enzovoort :)
toegevoegd de auteur Esailija, de bron
Probeer console.log (Object.keys (that.data [0] .cards)); . Als dat niet werkt, probeer dan console.log (that.data [0] .cards.propertyIsEnumerable ("E")); Als dat niet werkt, probeer dan console.log (dat .data [0] .cards .__ lookupGetter __ ("E")); Als DAT NIET werkt, link naar de pagina: D
toegevoegd de auteur Esailija, de bron
Hoe maak je het object, waar komt het vandaan? Heb je het op een schone pagina geïsoleerd?
toegevoegd de auteur Esailija, de bron