[object, object] in JavaScript – Meaning in JS
Ihechikara Vincent Abba
When working with objects in JavaScript, you may have come across the [object, object] output. While this may seem irrelevant, it’s not necessarily an error.
[object, object] is the string representation of a JavaScript object data type. You’ll understand better as we go further in this article.
There are two main contexts where you’ll encounter such an output:
- When you try display an object using the alert() method (most common).
- When you use the toString() method on an object.
Let’s take a look at some examples.
What Happens If You Alert an Object in JavaScript?
In this section, you’ll see what happens when you use the alert() method to display an object in JavaScript. Here’s the code example:
const student = < name: "John", school: "freeCodeCamp", >; alert(student)
In the code above, we created an object called student . After using the alert() method to display the object in the browser, we got the output below:
From the image above, instead of having the object and its properties displayed, [object, object] was displayed.
This happens because when you use the alert() method to display an object in JavaScript, you get the string format displayed.
To fix this, you can use the JSON.stringify() method to change the object into a string that can be popped up in the browser using the alert() method. Here’s an example:
const student = < name: "John", school: "freeCodeCamp", >; alert(JSON.stringify(student));
When you run the code above, you should have the object and its properties displayed – similar to the image below.
What Happens When You Use the toString() Method on an Object in JavaScript?
The toString() method in JavaScript returns the string format of an object. This section will help you understand what happened under the hood in the last section.
When you use the toString() method on an object in JavaScript, you get the string representation – [object, object] – returned.
const student = < name: "John", school: "freeCodeCamp", >; console.log(student.toString()); // [object Object]
As you can see in the code above, we used the toString() method on an object called student : student.toString() .
When we logged this to the console, we got [object, object] .
This effect is exactly what happens when you pop up an object in the browser using the alert() method (as we saw in the last section).
Summary
In this article, we talked about the odd looking [object, object] output in JavaScript.
We got to understand that the output is the string representation of an object data type in JavaScript.
You’re most likely going to see such an output when you try to display an object in the browser using the alert() method, or when you use the toString() method on an object.
We also went through some code examples and images to demonstrate how you can see [object, object] in JavaScript.
Выводит [object Object] при получении значения из массива
А где тут у вас массив? Вижу объект состоящий из объектов. Попробуйте alert(JSON.stringify(data.comments[«1»])) и получите первый объект.
7 авг 2018 в 4:22
Damon Haswell, попробовал, в ответ все тот же [object Object]
7 авг 2018 в 4:32
Выводит первый элемент объекта jsfiddle.net/xpvt214o/561117
7 авг 2018 в 4:35
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
В вашем коде было неявное преобразование из объекта в строку, что и даёт результат в виде [object Object] . Используйте JSON.stringify() для явного преобразования объекта в строку json формата.
Отслеживать
ответ дан 7 авг 2018 в 4:51
1,522 9 9 серебряных знаков 18 18 бронзовых знаков
- javascript
- массивы
- json
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
$mol_strict: Как же меня [object Object] этот ваш undefined NaN
Здравствуйте, меня зовут Дмитрий Карловский и я… не прощаю ошибок. Как только вижу оную — тут же бросаю что-нибудь исключительно тяжёлое. И как же тяжела работа программиста на JS.
class Foo extends Object < get name()< return 'Jin' >> const foo = new Foo `Здравствуйте, $< foo >!` // "Здравствуйте [object Object]!" `В этом месяце вы заработали $ < foo / 1000 >тысяч рублей.` // "В этом месяце вы заработали NaN тысяч рублей." `Ваша цель "$< 'foo'[4] >" наконец-то достигнута.` // "Ваша цель "undefined" наконец-то достигнута." `Осталось ещё $ < foo.length - 1 >целей и вы достигнете успеха.` // "Осталось ещё NaN целей и вы достигнете успеха." foo.__proto__= < name: 'придурок' >; `До скорых встреч, $< foo.name >.` // "До скорых встреч, придурок."
Облегчить его страдания можно разными путями..
- Прикрыться тайпскриптом. Но в рантайме ноги всё равно остаются босыми, и на них кто-нибудь вечно наступает.
- Обложиться проверками. Но чуть замешкаешься и рантайм грабли тут же бьют по голове.
- Исправить JS. Даже не надейтесь.
- Исправить JS рантайм. Ну, давайте подумаем..
Проблемы с динамической типизацией JS возникают по 3 основным причинам:
- Автоматическое (и порой неуместное) приведение типов, когда значение одного типа используется в контексте, предназначенном для другого, вместо сообщения об ошибке.
- Возврат undefined в качестве значения не объявленных полей вместо сообщения об ошибке.
- Случайное или злонамеренное изменение всего прототипа, при установке значения одного поля, вместо изменения только этого поля.
Сначала разберёмся с первой проблемой. JS устроен так, что приведение примитивных типов мы никак исправить не сможем. А вот за приведением объектов у нас есть полный контроль. Поэтому давайте пропатчим глобальный прототип всех объектов, чтобы никакие объекты по умолчанию не допускали приведения типов:
Object.prototype[ Symbol.toPrimitive ] = function()
Теперь, чтобы разрешить приведение типа, нужно переопределить метод Symbol.toPrimitive у нужного объекта.
Ладно, с первой проблемой разобрались. Но как-то она далась нам подозрительно легко… Что-то тут не так! Не похоже это на Веб… Ну да ладно, пошли к следующей.
Тут нам нужно как-то перехватывать обращения к произвольным полям объекта, даже если они ещё никак не были объявлены. В JS для этого есть только один механизм — прокси. Что ж, напишем такой прокси который при обращении к любому полю громко ругается квазицензурными словами:
export let $mol_strict_object = new Proxy( <>, < get( obj: object, field: PropertyKey, proxy: object ) < const name = JSON.stringify( String( field ) ) throw new TypeError( `Field $< name >is not defined` ) >, >)
К сожалению, поменять prototype у Object , как мы это сделали ранее, браузер нам уже не даст. Как и поменять прототип у Object.prototype — он всегда будет null . Зато мы можем менять прототипы у почти всех остальных стандартных классов унаследованных от Object :
Поэтому пройдёмся по всем глобальным переменным:
for( const name of Reflect.ownKeys( $ ) ) < // . >
Отсеем те из них, кто не является классами:
const func = Reflect.getOwnPropertyDescriptor( globalThis, name )!.value if( typeof func !== 'function' ) continue if(!( 'prototype' in func )) continue
Обратите внимание, что мы не используем globalThis[name] для получения значения, чтобы не триггерить ненужные варнинги.
Теперь оставляем лишь те классы, что непосредственно унаследованы от Object :
const proto = func.prototype if( Reflect.getPrototypeOf( proto ) !== Object.prototype ) continue
И, наконец, подменяем прототип прототипа с Object.prototype на наш строгий вариант:
Reflect.setPrototypeOf( proto, $mol_strict_object )
Теперь почти все стандартные объекты будут смотреть на вас с укоризной, при обращении к свойству, которому не задано значение. Ведь если значение задано, то браузер не пойдёт по цепочке прототипов и не дойдёт до нашего прокси.
К сожалению, есть и исключения, такие как сам Object, все объектные литералы и всё, что унаследовано от EventTarget, который тоже не дают менять.
И тут CSSStyleDeclaration делает нам подножку: если подменить его прототип на прокси (даже прозрачный, не кидающий исключений), то, внезапно, в Хроме 89 он перестаёт синхронизироваться с атрибутом style dom-элемента:
( > /> ).outerHTML //
Поэтому его пока что приходится вносить в исключения.
Есть и ещё одна беда… Если объявлять прикладные классы так:
class Foo <>
То объекты этих классов не будут строгими. Но если объявить их так:
class Foo extends Object <>
То… ничего особо не изменится. Но вот если подменить глобальный объект Object на свой строгий подкласс:
globalThis.Object = function $mol_strict_object( this: object, arg: any ) < let res = Object_orig.call( this, arg ) return this instanceof $mol_strict_object ? this : res >Reflect.setPrototypeOf( Object, Reflect.getPrototypeOf(<>) ) Reflect.setPrototypeOf( Object.prototype, $mol_strict_object )
То прикладные классы, явно унаследованные от Object , станут строгими.
Что ж, попарились на славу, другое дело. Последняя же проблема решается снова просто — удаляем геттер и сеттер для свойства __proto__ в результате чего, оно перестанет менять прототип объекта, а будет самым обычным полем, как и все остальные:
delete Object.prototype.__proto__
Однако, подчеркну, что если вы используете deep merge или deep compare, то в них необходимо проверять, что поле является собственным и игнорировать все остальные:
function merge_deep( left: object, right: object ) < for( let key of Reflect.ownKeys( right ) ) < if( left[ key ] && typeof left[ key ] === 'object' && right[ key ] && typeof right[ key ] === 'object' && Object.getOwnPropertyDescriptor( left, key ) ) < merge_deep( left[ key ], right[ key ] ) >else < left[ key ] = right[ key ] >> return left >
Иначе через такие стандартные свойства любого объекта, как contructor , toLocaleString и другие, можно будет дойти чуть ли не до любого объекта в приложении, что является лишним при работе с POJO.
Итак, что у нас получилось.
class Foo extends Object < get name()< return 'Jin' >> const foo = new Foo `Здравствуйте, $< foo >!` // TypeError: Field "Symbol(Symbol.toPrimitive)" is not defined `В этом месяце вы заработали $ < foo / 1000 >тысяч рублей.` // TypeError: Field "Symbol(Symbol.toPrimitive)" is not defined `Ваша цель "$< 'foo'[4] >" наконец-то достигнута.` // TypeError: Field "4" is not defined `Осталось ещё $ < foo.length - 1 >целей и вы достигнете успеха.` // TypeError: Field "length" is not defined foo.__proto__= < name: 'придурок' >; `До скорых встреч, $< foo.name >.` // "До скорых встреч, Jin."
На случай, если это будут читать дети, подчеркну:
Не меняйте поведение рантайма в библиотеках, ибо таким образом вы можете сломать кому-нибудь приложение. А вот для запуска тестов лучше использовать как раз максимально строгий рантайм — мало ли использовать вашу библиотеку будут именно в нём.
Если хотите лучше понять как всё это работает, то гляньте эту статью: Насколько JavaScript сильный?.
Полные исходники можно найти тут: $mol_strict.
Для подключения к своему NPM проекту достаточно прописать где-нибудь в начале точки входа:
import "mol_strict"
require("mol_strict")
Другие независимые сборки микробиблиотек из $mol можно найти тут: $mol: Usage from NPM ecosystem.
А если хотите обсудить подноготную JS рантайма, то присоединяйтесь к этим чатам:
- У браузера под юбкой (Обсуждаем разработку браузерных движков. Парсинг, рендеринг, архитектура, вот это всё.)
- UfoStation Chat (ФП — Фронтенд и Программирование.)
Наконец, в Твиттере _jinnin можно обнаружить много свежих мыслей на тему фронтенда, JS, UX и прочей дичи.
Object
Тип Object представляет один из типов данных JavaScript. Он используется для хранения различных коллекций с ключами и более сложных сущностей. Объекты могут быть созданы с использованием конструктора Object() (en-US) или синтаксиса инициализатора / литерала объекта.
Синтаксис
// Инициализатор объекта или литерал [ nameValuePair1[, nameValuePair2[, . nameValuePairN] ] ] > // Вызов в качестве конструктора new Object([value])
Параметры
Пары из имён (строки) и значений (любые значения), где имя отделяется от значения двоеточием.
Описание
Конструктор Object создаёт объект-обёртку для переданного значения. Если значением является null или undefined , создаёт и возвращает пустой объект, в противном случае возвращает объект такого типа, который соответствует переданному значению. Если значение уже является объектом, конструктор вернёт это значение.
При вызове в не-конструктором контексте, Object ведёт себя идентично коду new Object() .
Свойства конструктора Object
Имеет значение 1.
Позволяет добавлять свойства ко всем объектам типа Object .
Методы конструктора Object
Создаёт новый объект путём копирования значений всех собственных перечислимых свойств из одного или более исходных объектов в целевой объект.
Создаёт новый объект с указанными объектом прототипа и свойствами.
Добавляет к объекту именованное свойство, описываемое переданным дескриптором.
Добавляет к объекту именованные свойства, описываемые переданными дескрипторами.
Замораживает объект: другой код не сможет удалить или изменить никакое свойство.
Возвращает дескриптор свойства для именованного свойства объекта.
Возвращает массив, содержащий имена всех переданных объекту собственных перечисляемых и неперечисляемых свойств.
Возвращает массив всех символьных свойств, найденных непосредственно в переданном объекте.
Возвращает прототип указанного объекта.
Определяет, являются ли два значения различимыми (то есть, одинаковыми)
Определяет, разрешено ли расширение объекта.
Определяет, был ли объект заморожен.
Определяет, является ли объект запечатанным (sealed).
Возвращает массив, содержащий имена всех собственных перечислимых свойств переданного объекта.
Асинхронно наблюдает за изменениями в объекте.
Предотвращает любое расширение объекта.
Предотвращает удаление свойств объекта другим кодом.
Устанавливает прототип (т.е. внутреннее свойство [[Prototype]] )
Экземпляры и прототип объекта Object
Все объекты в JavaScript являются потомками Object ; все объекты наследуют методы и свойства из прототипа объекта Object.prototype (en-US), хотя они и могут быть переопределены. Например, прототипы других конструкторов переопределяют свойство constructor и предоставляют свои собственные методы toString() . Изменения в объекте прототипа Object распространяются на все объекты до тех пор, пока свойства и методы, учитывающие эти изменения, не переопределяются дальше по цепочке прототипов.
Свойства
Превращает входные данные в объект.
Указывает функцию, которая создает прототип объекта.
Указывает на объект, который использовался в качестве прототипа при создании экземпляра объекта.
Методы
Связывает функцию со свойством, которое при обращении к нему выполняет эту функцию и возвращает ее возвращаемое значение.
Связывает функцию со свойством, которое при установке выполняет ту функцию, которая изменяет свойство.
Возвращает функцию, привязанную в качестве средства получения к указанному свойству.
Возвращает функцию, привязанную в качестве установщика к указанному свойству.
Возвращает логическое значение, указывающее, содержит ли объект указанное свойство как прямое свойство этого объекта, а не унаследованное через цепочку прототипов.
Возвращает логическое значение, указывающее, содержит ли объект указанное свойство как прямое свойство этого объекта, а не унаследованное через цепочку прототипов.
Возвращает логическое значение, указывающее, является ли указанное свойство свойством объекта enumerable own.
Возвращает строковое представление объекта.
Возвращает примитивное значение указанного объекта.
Примеры
Пример: использование Object с типами undefined и null
Следующие примеры сохраняют пустой объект Object в переменную o :
const o = new Object(); const o = new Object(undefined); const o = new Object(null);
Пример: использование Object для создания объектов Boolean
Следующий пример сохраняет объекты Boolean в переменную o :
// эквивалентно o = new Boolean(true); const o = new Object(true);
// эквивалентно o = new Boolean(false); const o = new Object(Boolean());
Спецификации
Specification |
---|
ECMAScript Language Specification # sec-object-objects |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 20 окт. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.