# 00. Objects

Everything in JavaScript acts like an object, with the only two exceptions being `null` and `undefined`.

> **Объект** — это коллекция свойств, имеющая также связанный с ней объект-прототип. Прототипом является либо также объект, или же значение `null`.

Объект является неупорядоченной коллекцией **свойств**, каждое из которых имеет **имя** (*ключ*) и **значение**.

* Именем свойства может быть любая строка, включая и пустую строку.
* Значением свойства может быть любое значение, допустимое в языке JavaScript, или функция чтения или записи (или обе).
* Кавычки возле имени свойства указывать не обязательно, если это имя допустимо в JS и не является ключевым словом.

Терминология:

* **Базовый (Библиотечный) объект/класс** – это объект или класс объектов, определяемый спецификацией ES. Массивы, функции, даты и регулярные выражения (например) являются базовыми объектами.
* **Объект среды выполнения** – это объект, определяемый средой выполнения (такой как веб-броузер).
* **Пользовательский объект** – любой объект, созданный в результате выполнения программного кода JavaScript.

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

* **Собственное свойство** – это свойство, определяемое непосредственно в данном объекте.
* **Унаследованное свойство** – это свойство, определяемое прототипом объекта.
* **Свойства-методы доступа** - это специальные свойства, при обращении к которым выполняются функции.
* **Внутренние свойства** - это свойства объекта, играющие служебную роль. Например свойство `prototype`, или свойства задаваемые через well-known symbols.

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

* `writable` - определяет доступность значения свойства для записи.
* `enumerable` - определяет доступность имени свойства для перечисления в цикле `for/in`.
* `configurable` - определяет возможность модификации свойства, т. е. удаления свойства и изменения его атрибутов.

Объекты, хоть и являются ассоциативными массивами, но не являются *картами* в полном смысле этого слова. Т.е. объекты являются псевдоструктурами данных, с которыми связано множество синтаксических и логических нагромождений. Если нужны структуры данных как карты, то в ES6 появились полноценные структуры `Map` и `Set`.

Объект можно конвертировать в:

* Строку - `obj.toString()`, `Symbol.toStringTag`;
* Примитив - `obj.valueOf()`, `Symbol.toPrimitive`;
* JSON - `JSON.stringify(obj)`.

В JS между объектами действует прототипное наследование. Ключевые моменты прототипной организации JS:

* Все объекты являются экземплярами класса `Object`, а их прототипом является `Object.prototype`.
* Каждый объект может иметь прототип которому он делегирует выполнение операций, если он сам не может их выполнить;
* Прототип объекта может быть изменён в любое время программы;
* Изменение характеристик прототипа отображается на всех объектах, связанных с этим прототипом;
* Изменение над объектом всегда затрагивает только сам объект и не касается его прототипа.
