Не удается получить доступ к свойству объекта, даже если оно отображается в журнале консоли


329

Ниже вы можете увидеть результаты этих двух журналов. Первый четко показывает полный объект со свойством, к которому я пытаюсь получить доступ, но в следующей строке кода я не могу получить к нему доступ config.col_id_3(см. «Undefined» на скриншоте?). Кто-нибудь может объяснить это? Я могу получить доступ к любой другой собственности, кроме field_id_4как также.

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

Это то, что эти строки печатают в консоли

Консольный вывод


6
Можете ли вы попробовать console.log(JSON.stringify(config));и поделиться O / P
Арун P Johny

2
также попробуйте это, если это работает console.log (config ['col_id_3']);
zzlalani

5
это сработало для меня. использование строкового вывода в качестве нового ввода для рабочего объекта: JSON.parse (JSON.stringify (obj))
Tope

2
Стригирование, а затем разбор не решили проблему для меня, по некоторым причинам. Однако, прямой разбор сделал. JSON.parse(obj)
JacobPariseau

3
Почему-то все ответы объясняют, как зарегистрировать объект без ключа, а не как получить доступ к ключу
remidej

Ответы:


296

Вывод console.log(anObject)вводит в заблуждение; состояние отображаемого объекта разрешается только при расширении> в консоли. Это не состояние объекта, когда вы console.logбыли объектом.

Вместо этого попробуйте console.log(Object.keys(config)) или даже, console.log(JSON.stringify(config))и вы увидите ключи или состояние объекта во время вызова console.log.

Вы (обычно) обнаружите, что ключи добавляются после вашего console.logзвонка.


11
Это поведение ошибка или особенность? Если это особенность, в чем причина?
ESR

2
Как можно обойти это тогда? Установка таймаута НЕ кажется хорошим решением.
Саханд

9
Тогда как мы можем получить доступ к этому свойству, из объекта?
Рохит Шарма

Чтобы выяснить, отличается ли поведение >кнопки в зависимости от того, расширяется ли массив или объект?
Flimm

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

62

У меня только что была эта проблема с документом, загруженным из MongoDB с использованием Mongoose .

При запуске console.log()всего объекта все поля документа (как хранятся в БД) будут отображаться. Тем не менее, некоторые отдельные свойства собственности вернутсяundefined , когда другие (в том числе _id) будут работать нормально.

Оказалось, что методы доступа к свойствам работают только для тех полей, которые указаны в моем mongoose.Schema(...)определении, тогда как console.log()иJSON.stringify() возвращает все поля, хранящиеся в БД.

Решение (если вы используете Mongoose) : убедитесь, что все ваши поля БД определены в mongoose.Schema(...).


Отличное объяснение этой проблемы, я подумал, что Mongoose позволит мне запрашивать JSON без схемы (во внешнем скрипте), но будет предотвращать запись. Кажется, это работает, потому что _id присутствует, а console.log говорит, что все остальное должно быть доступно, но это не так. Bizarre.
bstar

7
Оказывается, я видел это, потому что JSON.stringify()(и Node's console.log()) меняют свое поведение, если данный объект имеет .toJSON()функцию. Вывод, который вы видите, - это то .toJSON(), что возвращает, а не исходный объект. Mongoose дает вам модельные объекты с тем, .toJSON()который дает базовый объект БД. Объект модели имеет средства доступа только к полям, которые вы определяете в схеме, но тогда все поля db появляются, когда вы регистрируете его, потому что вы на самом деле видите базовый объект, возвращаемый .toJSON().
Рамин

Почему мангуста не позволяет читать другие свойства, у вас есть идеи?
Kannan T

Это было полезно для меня при загрузке CSV в mongodb и получении собственности. Убедитесь, что ваши имена совпадают. Отличный ответ, спасибо.
9BallOnTheSnap

1
Спасибо тебе за это. Я сходил с ума, увидев его в консоли и не имея возможности получить к нему доступ. Добавил значение в мою схему, и я готов. Еще раз спасибо!
Alittletf

27

Проверьте, есть ли внутри объекта массив объектов. У меня была похожая проблема с JSON:

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

Я попытался получить доступ к ключу «name» из «category» и получил неопределенную ошибку, потому что я использовал:

var_name = obj_array.terms.category.name

Затем я понял, что у него квадратные скобки, это означает, что у него есть массив объектов внутри ключа категории, потому что он может иметь более одного объекта категории. Итак, чтобы получить ключ 'name', я использовал это:

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

И это делает трюк.

Возможно, уже слишком поздно для этого ответа, но я надеюсь, что кто-то с той же проблемой найдет это, как я, прежде чем найти решение :)


23

Я была такая же проблема. Решением для меня было использование строкового вывода в качестве входных данных для анализа JSON. это сработало для меня. надеюсь, что это полезно для вас

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

2
Да, это сработало, но зачем это нужно? У меня уже есть JSON, зачем мне это делать?
Джайн

@dilpeshjain Я не совсем уверен, но я рискну предположить, что у нас на самом деле уже нет JSON (возможно, происходит сценарий с отложенным типом загрузки, я не достаточно осведомлен об этом в данный момент), но пропускаю то, что у нас есть в JSON.stringify требуется, чтобы была возвращена строка (как для вызова требуется вызов console.log). Поскольку я знаю, что могу, по крайней мере, получить строку, то я могу использовать эту строку, чтобы точно создать объект JSON.
Топ

4
@jain вам это нужно, потому что javascript - ужасный язык

22

Свойство, к которому вы пытаетесь получить доступ, может еще не существовать. Console.log работает, потому что он выполняется после небольшой задержки, но это не относится к остальной части вашего кода. Попробуй это:

var a = config.col_id_3;    //undefined

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

}, 100);

1
Я использовал метод onload, чтобы получить значения моего объекта. Но в первый раз все еще дает мне неопределенность .. Этот язык делает меня мертвым день ото дня
Teoman Tıngır

простое решение состояло бы в том, чтобы реализовать обещание наблюдателя, которое проверяет, определено ли желаемое свойство с помощью setTimeout, и решает + очищает время ожидания, как только свойство становится доступным.
Лай Сюэ

Вот это да. За мои 15 лет веб-программирования я никогда не сталкивался с этим и никогда не задумывался о том, как работает консольный журнал. Ваш ответ помог прояснить некоторые из них.
Кай Цин

12

В моем случае я передавал объект обещанию, в рамках обещания я добавлял дополнительные ключи / значения к объекту, и когда это было сделано, обещание возвращало объект.

Тем не менее, с моей стороны был небольшой надзор, обещание возвращало объект до того, как он был полностью завершен ... таким образом, остальная часть моего кода пыталась обработать обновленный объект, а данные еще не были там. Но, как и выше, в консоли я увидел, что объект полностью обновлен, но не смог получить доступ к ключам - они возвращались неопределенными. Пока я не увидел это:

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*

[Я] - маленькая иконка, когда я завис над ней, она сказала Object value at left was snapshotted when logged, value below was evaluated just now. Вот когда мне пришло в голову, что мой объект оценивается до того, как обещание полностью обновило его.


10

Я боролся с этой проблемой сегодня, и думал, что оставлю ответ со своим решением.

Я выбирал объект данных через ajax, что-то вроде этого: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Допустим, этот объект находится в переменной с именем data. Всякий раз, когда я ссылался, data.i18nя получил undefined.

  1. console.log(data) показал объект, как и ожидалось
  2. console.log(Object.keys(data))сказал, ["constants","i18n"]как и ожидалось
  3. Переименование i18n в inter ничего не изменило
  4. Я даже пытался переключить данные, чтобы сделать «i18n» первым объектом
  5. Переместил код, чтобы убедиться, что объект полностью настроен, и с обещанием ajax проблем не было.

Ничего не помогло ... Затем на стороне сервера я записал данные в журнал php, и он показал это:

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

«I» в ключе индекса было на самом деле u0456 (кириллица i). Это не было видно в моем редакторе php или журнале консоли браузера. Только журнал php показал это ... Это было сложно ...


1
Это было также моей проблемой; вместо этого в некоторых случаях использовался кириллический символ «с». Я нашел это, ища в моем файле строку, которую я ожидал; подозрительный не был выбран, поэтому он сказал мне, что был неправильный персонаж, который был невидим для глаза.
рыцарь

Этот ответ действительно помог мне найти свое решение. Моя проблема была в том, что я неправильно написал имя переменной. Я сделал «обновление» вместо «обновления» LOL
Савлон

8

Мои данные были просто строкой данных JSON. (Эта переменная была сохранена как строка json в сеансе).

console.log(json_string_object)

-> возвращает только представление этой строки, и нет никакого способа сделать различие, является ли строка или объект.

Итак, чтобы заставить его работать, мне просто нужно было преобразовать его обратно в реальный объект:

object = JSON.parse(json_string_object);

Это был единственный ответ, который работал для меня и также упоминается в комментариях к исходному вопросу, это должно быть выше.
abagh0703

5

В 2018 году Mozilla предупреждает нас в Документах Mozilla здесь !

Я цитирую "Регистрация объектов" :

Не используйте console.log(obj);, используйте console.log(JSON.parse(JSON.stringify(obj)));.

Таким образом, вы уверены, что видите значение obj в тот момент, когда вы его регистрируете.


4

Это может кому-то помочь, так как у меня была похожая проблема, в которой JSON.parse () возвращал объект, который я мог напечатать на console.log (), но я не мог получить доступ к определенным полям, и ни одно из вышеупомянутых решений не работало для меня. Как использование комбинации JSON.parse () с 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  

Я решил проблему с помощью другого парсера, предоставленного ExtJs Ext.decode ();

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

2

В моем случае, так получилось, что, хотя я получаю данные в формате объекта модели, myMethod(data:MyModelClass) пока полученный объект не будет иметь тип string. Который у в console.log (данные) я получаю содержимое. Решение - просто проанализировать JSON (в моем случае)

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

Мысль может быть полезной.


2

Я только что столкнулся с этой проблемой с объектами, сгенерированными csv-parser из файла CSV, сгенерированного MS Excel. Я был в состоянии получить доступ ко всем свойствам, кроме первого свойства - но это было бы хорошо, если бы я написал весь объект, используя console.log.

Оказалось, что формат CSV UTF-8 вставляет 3 байта (ef bb bf) в начале, соответствующие невидимому символу - которые были включены как часть первого заголовка свойства csv-parser. Решение состояло в том, чтобы заново сгенерировать CSV, используя опцию не-UTF, и это исключило невидимый символ.


Вы герой! Спасибо за публикацию этого. Я вырывал свои волосы.
Джордан С

Еще раз спасибо за размещение этого! Спас мою ночь!
Оливер Хикман

2

У меня была похожая проблема, надеюсь, следующее решение кому-нибудь поможет.
Ты можешь использоватьsetTimeout функцию, как предлагают некоторые парни, но вы никогда не знаете, сколько именно времени требуется вашему браузеру для определения вашего объекта.

Из этого я бы предложил setIntervalвместо этого использовать функцию. Он будет ждать, пока ваш объект не config.col_id_3будет определен, а затем запустит вашу следующую часть кода, которая требует ваших конкретных свойств объекта.

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

});

2

если вы используете TYPESCRIPTи / или ANGULAR, это может быть так!

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

установив тип ответа на любой исправил эту проблему для меня, я не мог получить доступ к свойствам ответа, пока я не установил res: any

см. этот вопрос Свойство '_body' не существует для типа 'Ответ'


1

У меня была та же проблема, и ни одно из вышеперечисленных решений не сработало для меня, и после этого мне показалось, что это похоже на догадки. Однако завершение моего кода, который создает объект в setTimeoutфункции, помогло мне.

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

У меня была похожая проблема или, возможно, только что связанная.

В моем случае я обращался к свойствам объекта, но один не был определен. Я обнаружил, что проблема была в пробелах в коде на стороне сервера при создании ключа val объекта.

Мой подход был следующим ...

создавая мой объект ... обратите внимание на пробел в слове

ответ я получаю от моего REST API

код JavaScript для регистрации значений

записывать результаты с консоли

После удаления пробела из серверного кода, создающего объект, я теперь могу получить доступ к свойству, как показано ниже ...

результат после удаления пробелов

Это может не быть проблемой в случае предметного вопроса, но было для моего случая и может быть таковым для кого-то еще. Надеюсь, поможет.


1

У меня была такая же проблема с документом, загруженным из MongoDB с использованием Mongoose.

Оказалось, что я использую свойство, find()чтобы вернуть только один объект, поэтому я перешел find()на findOne()и все работало для меня.

Решение (если вы используете Mongoose): убедитесь, что вы возвращаете только один объект, чтобы вы могли разобрать его, object.idили он будет обрабатываться как массив, поэтому вам нужно получить к нему доступ таким образом object[0].id.


1

Для меня это оказалось проблемой Мангуста.

Я перебирал объекты, полученные из запроса Монго. Я просто должен был удалить:

items = await Model.find()

И заменить его на:

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

0

У меня была такая проблема, и я нашел, что решение было связано с Underscore.js. Моя первоначальная регистрация не имела смысла:

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

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

console.log(obj.code);

> undefined

Я нашел решение, также посмотрев на ключи объекта:

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

> ["_wrapped","_chain"]

Это привело меня к пониманию того, что obj самом деле это был обертка Underscore.js вокруг объекта, и первоначальная отладка была для меня ложью.


0

У меня была похожая проблема (при разработке для SugarCRM), где я начинаю с:

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

Проблема была в fetch(), его асинхронный вызов, поэтому мне пришлось переписать мой код в:

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

На всякий случай, если это кому-то полезно, у меня была похожая проблема, потому что кто-то создал переопределение для .toJSON в объекте, с которым я работал. Таким образом, объект был что-то вроде:

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

Но .toJSON () было:

toJSON() {
  return this.foo
}

Поэтому, когда я вызвал JSON.stringify (myObject), он вернул "{" bar ":" Hello "," baz ":" World "}". Однако Object.keys (myObject) обнаружил «foo».


toJson()это точка, которую никто здесь не упомянул. Я не знаю, почему этот ответ был отвергнут, поскольку это способ создать объект, значение которого отличается от его представления в json или в консоли. Я не знал, что он существует, пока не раскрыл его в другом ответе, и я думаю, что за этот ответ следует проголосовать, так как это вопрос, который следует учитывать при рассмотрении подобных вопросов.
Рик Лав

Учитывая количество ответов, которые имеют ровно 0 баллов, я думаю, что кто-то просто прошел через все.
emote_control

0

Я столкнулся с той же проблемой сегодня. В моем случае ключи были вложенными, т.е. key1.key2. Я разделил ключи, используя split (), а затем использовал обозначение в квадратных скобках, которое мне помогло.

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

Я разделил ключи и использовал их следующим образом: data [key1] [key2], которые сделали эту работу за меня.


0

У меня была такая же проблема сегодня. Проблема была вызвана uglify-js. После того, как я выполнил тот же самый код без исправлений, проблема была решена. Удаление из

--mangle-props

от uglify-js было достаточно иметь рабочий код uglified.

Возможно, лучше всего использовать какой-то префикс для свойств, которые должны быть искажены с помощью правила регулярных выражений для uglify-js.

Вот источник:

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

и вот как это было увеличено:

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

0

Ни один из JSON stringify / parse не работал для меня.

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

Я хотел значение formValues.myKeyи что трюк был setTimeout 0, как в примере ниже. Надеюсь, поможет.

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

0

Я только что столкнулся с этой проблемой, и короче говоря, мой API возвращал строковый тип, а не JSON. Так что это выглядело точно так же, когда вы печатали его в журнале, однако всякий раз, когда я пытался получить доступ к свойствам, я получал неопределенную ошибку.

Код API:

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

ранее я только возвращался:

return Json(string Of object);

0

У меня была похожая проблема сегодня в React. В конце концов понял, что проблема была вызвана состоянием еще не устанавливается. Я звонил, user.user.nameи хотя он отображался в консоли, я не мог получить к нему доступ в своем компоненте, пока не включил проверку, чтобы проверить, user.userбыл ли установлен, а затем позвонил user.user.name.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.