Объекты
Чему вы научитесь:
- собирать данные в объект и читать его свойства через точку и квадратные скобки;
- перебирать ключи и значения объекта и объяснять, в каком порядке они идут;
- писать методы и отличать копию объекта от второй ссылки на тот же объект;
- раскладывать объект по переменным и безопасно читать вложенные свойства через
?..

Представьте анкету в отделе кадров. В ней строки с подписями: «Имя», «Возраст», «Город». Чтобы узнать возраст, вы ищете не третью строку сверху, а строку с подписью «Возраст».
Массив так не умеет. Имя, возраст и город можно сложить в массив ["Ann", 30, "Oslo"], но его элементы различаются только индексами. По записи user[1] не понять, что там возраст.
Объект хранит каждое значение под своим именем, как анкета — под подписью строки:
const user = { name: "Ann", age: 30, city: "Oslo" };
console.log(user.name); // Ann
console.log(user["age"]); // 30
console.log(user); // { name: 'Ann', age: 30, city: 'Oslo' }
console.log(typeof user); // objectДавайте разберём пример по строкам:
- Первая строка создаёт объект с тремя свойствами и кладёт его в константу
user. user.nameнаходит значение с подписьюnameи печатаетAnn.user["age"]читает возраст через квадратные скобки — второй способ, о нём ниже.console.log(user)печатает весь объект в фигурных скобках, а строки внутри — в одинарных кавычках.typeof userдаётobject.
Свойства и ключи
Объект — набор свойств в фигурных скобках, разделённых запятыми. Свойство — пара из ключа и значения. Слева от двоеточия стоит ключ — имя свойства, справа — значение любого типа.
В анкете ключ — это подпись строки, а значение — то, что в строке написано.
Значением может быть и массив, и другой объект. Если записать const user = { name: "Ann", address: { city: "Oslo" } }, то до города ведёт цепочка точек: user.address.city.
Ключи в записи объекта пишут без кавычек, когда ключ похож на имя переменной.
Здесь аналогия с анкетой перестаёт работать. Строки бумажной анкеты напечатаны заранее, а в объект можно в любой момент дописать новое свойство или вычеркнуть старое.
Точка и квадратные скобки
Прочитать свойство можно двумя способами. После точки пишут имя ключа буквально: user.name читает свойство name. В квадратных скобках стоит выражение: JavaScript сначала вычисляет его, и результат становится ключом. Поэтому в скобках может стоять переменная:
const user = { name: "Ann", age: 30 };
const field = "name";
console.log(user[field]); // Ann
console.log(user.field); // undefined
console.log(user["na" + "me"]); // AnnРазберём, что читает каждая строка:
- В переменной
fieldлежит строка"name", поэтомуuser[field]читает свойствоname. user.fieldищет свойство с буквальным именемfield, которого у объекта нет. Отсутствующий ключ даётundefined, а не ошибку.user["na" + "me"]сначала склеивает строку"name", а затем читает свойство с этим ключом.
Скобки нужны и для ключа с пробелом или дефисом: user["home city"]. В записи объекта такой ключ берут в кавычки.
Какой способ выбрать:
- точку пишут, когда имя ключа известно заранее;
- скобки — когда ключ лежит в переменной или собирается из частей.
Изменение объекта
Четыре операции с ключами:
- присваивание по новому ключу добавляет свойство;
- присваивание по существующему ключу меняет его значение;
- оператор
deleteудаляет свойство; - оператор
inпроверяет, есть ли у объекта ключ, и даётtrueилиfalse.
Оператор in смотрит только на ключ: свойство со значением 0 или undefined для него всё равно есть.
const user = { name: "Ann" };
user.age = 30;
user.name = "Bob";
user["home city"] = "Oslo";
delete user.age;
console.log(user); // { name: 'Bob', 'home city': 'Oslo' }
console.log("age" in user, "name" in user); // false trueДавайте посмотрим, что происходит с анкетой user:
user.age = 30дописывает новое свойствоage.user.name = "Bob"меняет значение уже существующего свойства.user["home city"] = "Oslo"добавляет ключ с пробелом — через скобки.delete user.ageудаляет свойствоageцеликом, вместе с ключом.- Последняя строка печатает
false true: ключаageбольше нет, аnameесть.
Скобки работают и при записи. Если ключ лежит в переменной word, то counts[word] = 1 создаёт в объекте counts свойство с этим ключом.
Объект в const всё равно можно менять. const запрещает присвоить переменной другой объект, а свойства того же объекта остаются изменяемыми.
Свои и встроенные ключи
Оператор in видит не только те ключи, которые записали в объект. У каждого объекта, даже у пустого {}, есть встроенные ключи, общие для всех объектов, например toString и constructor. console.log их не печатает, а in находит.
На бланке анкеты так бывает со строкой, которую напечатала типография: вы её не заполняли, но она на каждом бланке.
Для объекта user из примера выше:
"toString" in userдаётtrue, хотя такой ключ вuserникто не записывал;Object.hasOwn(user, "toString")даётfalse;Object.hasOwn(user, "name")даётtrue.
Функция Object.hasOwn(obj, key) проверяет только свои ключи объекта — те, что в нём записаны. Её выбирают, когда ключи приходят из данных: из текста или от пользователя. Чтение counts["constructor"] у пустого объекта counts даёт не undefined, а встроенную функцию, и только Object.hasOwn скажет, что такого слова в counts ещё нет.
Частая ошибка
Ключ проверили через значение свойства:
const scores = { ann: 0, bob: 7 };
if (scores.ann) { // ✗
console.log("ann has a score");
} else {
console.log("no score for ann");
}Программа выводит no score for ann, хотя ключ ann в объекте есть. Его значение 0 — ложное, и if принимает его за отсутствие свойства. Есть ли ключ, проверяет "ann" in scores или Object.hasOwn(scores, "ann"): здесь оба дают true.
Главное
- Объект хранит значения под ключами:
{ name: "Ann", age: 30 }; отсутствующий ключ даётundefined. - После точки ключ пишут буквально, а в квадратных скобках сначала вычисляется выражение:
user[field]. - Присваивание добавляет или меняет свойство, а
deleteудаляет его. - Есть ли ключ, проверяют через
inилиObject.hasOwn, а не через значение;inвидит и встроенные ключи вродеtoString.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.