Перейти к содержимому
Теория · Объекты · урок 1 из 13

Объекты

Чему вы научитесь

Чему вы научитесь:

  • собирать данные в объект и читать его свойства через точку и квадратные скобки;
  • перебирать ключи и значения объекта и объяснять, в каком порядке они идут;
  • писать методы и отличать копию объекта от второй ссылки на тот же объект;
  • раскладывать объект по переменным и безопасно читать вложенные свойства через ?..
Анкета user из трёх строк: в строке с подписью age стоит значение 30

Представьте анкету в отделе кадров. В ней строки с подписями: «Имя», «Возраст», «Город». Чтобы узнать возраст, вы ищете не третью строку сверху, а строку с подписью «Возраст».

Массив так не умеет. Имя, возраст и город можно сложить в массив ["Ann", 30, "Oslo"], но его элементы различаются только индексами. По записи user[1] не понять, что там возраст.

Объект хранит каждое значение под своим именем, как анкета — под подписью строки:

JavaScript
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

Давайте разберём пример по строкам:

  1. Первая строка создаёт объект с тремя свойствами и кладёт его в константу user.
  2. user.name находит значение с подписью name и печатает Ann.
  3. user["age"] читает возраст через квадратные скобки — второй способ, о нём ниже.
  4. console.log(user) печатает весь объект в фигурных скобках, а строки внутри — в одинарных кавычках.
  5. typeof user даёт object.

Свойства и ключи

Объект — набор свойств в фигурных скобках, разделённых запятыми. Свойство — пара из ключа и значения. Слева от двоеточия стоит ключ — имя свойства, справа — значение любого типа.

В анкете ключ — это подпись строки, а значение — то, что в строке написано.

Значением может быть и массив, и другой объект. Если записать const user = { name: "Ann", address: { city: "Oslo" } }, то до города ведёт цепочка точек: user.address.city.

Ключи в записи объекта пишут без кавычек, когда ключ похож на имя переменной.

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

Точка и квадратные скобки

Прочитать свойство можно двумя способами. После точки пишут имя ключа буквально: user.name читает свойство name. В квадратных скобках стоит выражение: JavaScript сначала вычисляет его, и результат становится ключом. Поэтому в скобках может стоять переменная:

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

Разберём, что читает каждая строка:

  1. В переменной field лежит строка "name", поэтому user[field] читает свойство name.
  2. user.field ищет свойство с буквальным именем field, которого у объекта нет. Отсутствующий ключ даёт undefined, а не ошибку.
  3. user["na" + "me"] сначала склеивает строку "name", а затем читает свойство с этим ключом.

Скобки нужны и для ключа с пробелом или дефисом: user["home city"]. В записи объекта такой ключ берут в кавычки.

Какой способ выбрать:

  • точку пишут, когда имя ключа известно заранее;
  • скобки — когда ключ лежит в переменной или собирается из частей.

Изменение объекта

Четыре операции с ключами:

  • присваивание по новому ключу добавляет свойство;
  • присваивание по существующему ключу меняет его значение;
  • оператор delete удаляет свойство;
  • оператор in проверяет, есть ли у объекта ключ, и даёт true или false.

Оператор in смотрит только на ключ: свойство со значением 0 или undefined для него всё равно есть.

JavaScript
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:

  1. user.age = 30 дописывает новое свойство age.
  2. user.name = "Bob" меняет значение уже существующего свойства.
  3. user["home city"] = "Oslo" добавляет ключ с пробелом — через скобки.
  4. delete user.age удаляет свойство age целиком, вместе с ключом.
  5. Последняя строка печатает 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 ещё нет.

Частая ошибка

Ключ проверили через значение свойства:

JavaScript
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 и подпишись на канал — откроются все уроки.

Войти другим способом