Перейти к содержимому

6. Объекты

Иллюстрация к уроку Объекты — это фундаментальная структура данных в JavaScript, позволяющая хранить коллекции данных в виде пар “ключ-значение”. Ключи (или имена свойств) — это всегда строки (или символы), а значения могут быть любыми типами данных, включая другие объекты и функции.

Самый распространенный способ создания объекта — использование литерала объекта {}.

// Создание объекта с использованием литерала
const user = {
name: 'Алиса', // Свойство name со строковым значением
age: 30, // Свойство age с числовым значением
isAdmin: false // Свойство isAdmin с булевым значением
};
console.log(user.name); // Доступ к свойству через точку: 'Алиса'
console.log(user['age']); // Доступ к свойству через скобки: 30
// Скобочная нотация полезна, когда имя свойства динамическое
const key = 'isAdmin';
console.log(user[key]); // false

Свойства объектов можно легко добавлять, изменять и удалять.

const product = {
name: 'Ноутбук',
price: 1200
};
product.quantity = 5; // Добавление нового свойства
product['price'] = 1150; // Изменение существующего свойства
console.log(product); // { name: 'Ноутбук', price: 1150, quantity: 5 }
delete product.quantity; // Удаление свойства
console.log(product); // { name: 'Ноутбук', price: 1150 }

Функции, хранящиеся как свойства объекта, называются методами. Они позволяют объектам выполнять действия. Ключевое слово this внутри метода ссылается на сам объект.

const person = {
firstName: 'Боб',
lastName: 'Марли',
greet() {
// Внутри метода `this` указывает на текущий объект (person)
console.log(`Привет, меня зовут ${this.firstName} ${this.lastName}!`);
},
// ES6 сокращенная запись для методов (предпочтительна)
introduce() {
console.log(`Я ${this.firstName}.`);
}
};
person.greet(); // Привет, меня зовут Боб Марли!
person.introduce(); // Я Боб.

Сокращенные имена свойств (Shorthand Property Names): Если имя переменной совпадает с именем свойства, можно использовать сокращенную запись.

const userName = 'Чарли';
const userAge = 25;
const newUser = {
userName, // То же что userName: userName
userAge // То же что userAge: userAge
};
console.log(newUser); // { userName: 'Чарли', userAge: 25 }

Деструктуризация объектов: Удобный способ извлекать свойства из объекта в отдельные переменные.

const settings = {
theme: 'dark',
fontSize: 16,
notifications: true
};
const { theme, fontSize } = settings; // Извлекаем theme и fontSize
console.log(theme, fontSize); // dark 16
const { notifications: notify } = settings; // Извлекаем notifications и переименовываем в notify
console.log(notify); // true

Spread-оператор (...) для объектов: Позволяет копировать свойства объекта или объединять несколько объектов.

const userProfile = { name: 'Диана', email: '[email protected]' };
const userPrefs = { theme: 'light', lang: 'ru' };
// Копирование объекта
const copiedProfile = { ...userProfile };
console.log(copiedProfile); // { name: 'Диана', email: '[email protected]' }
// Объединение объектов
const fullUser = { ...userProfile, ...userPrefs, isActive: true };
console.log(fullUser);
// { name: 'Диана', email: '[email protected]', theme: 'light', lang: 'ru', isActive: true }
// Переопределение свойств при объединении
const updatedUser = { ...userProfile, email: '[email protected]' };
console.log(updatedUser); // email будет перезаписан

Методы Object.keys(), Object.values() и Object.entries() позволяют получить массивы ключей, значений или пар “ключ-значение” соответственно.

const car = {
make: 'Honda',
model: 'Civic',
year: 2020
};
console.log(Object.keys(car)); // [ 'make', 'model', 'year' ]
console.log(Object.values(car)); // [ 'Honda', 'Civic', 2020 ]
console.log(Object.entries(car)); // [ ['make', 'Honda'], ['model', 'Civic'], ['year', 2020] ]
// Использование в циклах
for (const [key, value] of Object.entries(car)) {
console.log(`${key}: ${value}`);
}
// make: Honda
// model: Civic
// year: 2020

Мутация объектов (передача по ссылке): Объекты в JavaScript передаются по ссылке, а не по значению. Это значит, что если вы присвоите один объект другому, они будут ссылаться на одну и ту же область памяти.

const original = { value: 10 };
const reference = original; // reference теперь ссылается на тот же объект
reference.value = 20; // Изменяем value через reference
console.log(original.value); // 20! original тоже изменился.

Для создания независимой копии используйте spread-оператор или Object.assign():

const independentCopy = { ...original }; // Создает поверхностную копию
independentCopy.value = 30;
console.log(original.value); // 20 (original не изменился)
console.log(independentCopy.value); // 30

Геттеры и Сеттеры: Позволяют выполнять функции при доступе к свойству или его изменении, обеспечивая контролируемый интерфейс.

const rectangle = {
_width: 5, // Принято начинать имя свойства с '_' для внутренних данных
_height: 10,
get area() { // Геттер вызывается при обращении к rectangle.area
return this._width * this._height;
},
set dimensions(values) { // Сеттер вызывается при присваивании rectangle.dimensions = [...]
if (Array.isArray(values) && values.length === 2) {
this._width = values[0];
this._height = values[1];
}
}
};
console.log(rectangle.area); // 50
rectangle.dimensions = [6, 12];
console.log(rectangle.area); // 72
  • Используйте const для объектов: Хотя свойства объекта можно менять, саму ссылку на объект лучше объявлять через const, чтобы избежать случайного переприсваивания.
  • Иммутабельность: Старайтесь не изменять объекты напрямую, если это возможно. Вместо этого создавайте новые объекты с нужными изменениями, используя spread-оператор или Object.assign(). Это делает код предсказуемее, особенно в реактивных фреймворках.
  • Глубокое клонирование: Spread-оператор делает поверхностную копию. Если внутри объекта есть другие объекты, они по-прежнему будут переданы по ссылке. Для глубокого клонирования используйте библиотеки (например, Lodash cloneDeep) или JSON.parse(JSON.stringify(obj)) для простых случаев (без функций, дат и т.д.).
  • Читаемость: Называйте ключи осмысленно. Используйте camelCase для ключей.

Объекты — это основа JavaScript. Понимание того, как они работают, и эффективное использование их возможностей является ключевым для написания чистого, мощного и поддерживаемого кода.