Почему это свойство объекта undefined?

Рассмотрим приведенный ниже код. Первый console.log правильно регистрирует изображение, и вы можете увидеть его свойства на изображении ниже. Однако, когда я пытаюсь выполнить запись одного из них, если его свойства на консоли, я получаю 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

Результат в консоли:

enter image description here

Любая идея, что здесь происходит? Свойство xml внутри that.data[0] должно также иметь свойства внутри него - на самом деле оно называется тем же, что и свойства в cards.

FWIW, я получаю то же самое в Firebug (приведенный выше образ консоли - Chrome).

Ответ 1

Я решил проблему. В принципе, объект, о котором идет речь (that.data[0].cards), имеет свои свойства, созданные функцией a(), которая запускается после обработки всех запросов AJAX для необходимых файлов XML. Я разрешаю запросам работать асинхронно, используя счетчик для определения в функции обратного вызова success, если еще нужно вызывать a().

После выполнения a() функция b() должна выполнять операции над that.data[i].cards. Тем не менее, b() выполнялся до вызова a() из-за a() зависимости от асинхронных запросов. Таким образом, решение было просто сделать вызов a() b().

Так что это оказалось довольно простой ошибкой с моей стороны. Что сделало его настолько запутанным, так это то, что запись that.data[0].cards на консоль показала мне, что на самом деле объект cards уже был построен, а на самом деле он еще не был. Поэтому консоль предоставляла мне неправильную или, по крайней мере, неясную информацию.

Спасибо за помощь всем вчера вечером! Все вокруг:)

Ответ 2

Я думаю, что ключи объекта имеют непечатаемые символы, такие могут быть реплицированы следующим образом:

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

//[]

Изменить: вы можете увидеть, действительно ли это относится к вашим объектным клавишам:

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)

Edit2: Поскольку вы не можете этого сделать, я придумал другой способ увидеть, есть ли непечатаемые символы:

Скопируйте ключевую строку следующим образом: (зайдите так же, как и на обоих концах, чтобы выбрать любые невидимые символы)

jVrZz.png

Затем сбросьте буфер обмена таким образом (убедитесь, что вы используете двойные кавычки):

AsvSV.png