Методы Object: keys, entries, assign, freeze

Содержание

О проверке кода. Примеры не запускались — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».

Object — это не только способ создавать объекты, но и набор статических методов-утилит для работы с ними. Они превращают объект в то, с чем удобно работать как с массивом. Разберём самые нужные.

keys, values, entries — перебор

const user = { name: 'Аня', age: 30, city: 'Москва' };

Object.keys(user);      // ['name', 'age', 'city']
Object.values(user);    // ['Аня', 30, 'Москва']
Object.entries(user);   // [['name','Аня'], ['age',30], ['city','Москва']]

Три метода превращают объект в массив, к которому применимы все методы массивов:

// сумма всех числовых значений
const prices = { apple: 50, milk: 80, bread: 40 };
Object.values(prices).reduce((sum, p) => sum + p, 0);   // 170

// отфильтровать объект по условию
const cheap = Object.entries(prices).filter(([, price]) => price < 60);
// [['apple', 50], ['bread', 40]]

Это главная причина существования этих методов: объект сам по себе не итерируется через map/filter/reduce, а превращённый в массив пар — сколько угодно.

fromEntries — собрать обратно

const pairs = [['a', 1], ['b', 2]];
Object.fromEntries(pairs);   // { a: 1, b: 2 }

Object.fromEntriesобратная операция к entries. Вместе они дают паттерн «преобразовать объект как массив, потом собрать назад»:

const prices = { apple: 50, milk: 80 };

// поднять все цены на 10%
const raised = Object.fromEntries(
  Object.entries(prices).map(([name, price]) => [name, price * 1.1])
);
// { apple: 55, milk: 88 }

entriesmapfromEntries — стандартный конвейер трансформации объекта. Ещё fromEntries удобен для превращения Map или URLSearchParams в обычный объект.

assign — слить объекты

const defaults = { color: 'black', size: 'M' };
const custom = { color: 'red' };

Object.assign({}, defaults, custom);   // { color: 'red', size: 'M' }

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

Object.assign(defaults, custom);   // ❌ defaults ИЗМЕНЁН!
Object.assign({}, defaults, custom); // ✅ новый объект, оригиналы целы

Всегда передавайте {} первым, если не хотите испортить исходный объект. В современном коде для слияния чаще берут spread { ...defaults, ...custom } — короче и без риска случайной мутации.

freeze — защита от изменений

const config = Object.freeze({ port: 3000, host: 'localhost' });

config.port = 8080;      // молча игнорируется (в строгом режиме — TypeError)
config.newField = 1;     // тоже не сработает
delete config.host;      // и удалить нельзя

Object.isFrozen(config); // true

Object.freeze делает объект неизменяемым — нельзя менять, добавлять и удалять свойства. Полезно для констант-конфигураций, чтобы случайная мутация где-то в коде не сломала настройки.

Ловушка — заморозка поверхностная:

const state = Object.freeze({ user: { name: 'Аня' } });
state.user.name = 'Борис';   // ❌ СРАБОТАЕТ — вложенный объект не заморожен

freeze защищает только верхний уровень. Вложенные объекты нужно замораживать отдельно (рекурсивно) — это та же природа ссылок, что и при копировании.

hasOwn — проверка свойства

const user = { name: 'Аня', role: undefined };

Object.hasOwn(user, 'name');   // true  — собственное свойство
Object.hasOwn(user, 'role');   // true  — есть, хоть и undefined
Object.hasOwn(user, 'toString'); // false — унаследованное, не своё

Object.hasOwn(obj, key) — современная и надёжная проверка собственного свойства. Она заменила старый obj.hasOwnProperty(key), который ломался, если объект переопределил это имя или создан через Object.create(null). Проверять существование через сравнение с undefinedненадёжно: свойство может существовать со значением undefined.

Шпаргалка

Методы Object: что для чего

Читать и перебирать

Объект → массив

  • keys — ключи
  • values — значения
  • entries — пары [k, v]
  • hasOwn — есть ли своё свойство

Собирать и защищать

Массив → объект, защита

  • fromEntries — пары → объект
  • assign — слить (мутирует!)
  • freeze — запретить изменения
  • isFrozen — проверка заморозки

Смежные темы: объекты — создание и доступ; примитивы и ссылки — почему assign и freeze поверхностные; методы массива. Полный список — в уроках JavaScript.

Частые вопросы

Чем Object.keys отличается от for...in?
Object.keys возвращает массив собственных свойств объекта — к нему сразу применимы map и filter. for…in перебирает и унаследованные свойства из прототипа, поэтому требует проверки hasOwn внутри. В новом коде берут Object.keys.
Что делает Object.entries?
Возвращает массив пар [ключ, значение]: Object.entries({a:1}) даёт [[‘a’,1]]. Удобно для перебора через for…of с деструктуризацией и для превращения объекта в Map.
Как превратить массив пар обратно в объект?
Object.fromEntries: Object.fromEntries([[‘a’,1],[‘b’,2]]) даёт {a:1, b:2}. Это обратная операция к Object.entries — вместе они позволяют преобразовывать объект как массив.
Object.assign меняет исходный объект?
Да, первый аргумент (цель) мутируется — в него копируются свойства остальных. Чтобы не менять исходный, передайте пустой объект первым: Object.assign({}, a, b). Чаще для этого используют spread { …a, …b }.
Что именно замораживает Object.freeze?
Только верхний уровень объекта: нельзя менять, добавлять и удалять его свойства. Вложенные объекты остаются изменяемыми — freeze поверхностный. Для глубокой заморозки нужно рекурсивно заморозить вложенные.