Введение: Что такое объекты и зачем они нужны?
Привет, юный программист! 👋 Сегодня мы познакомимся с одной из самых важных тем в JavaScript — объектами. Если ты уже умеешь работать с числами, строками и массивами, то объекты станут твоим следующим шагом к созданию настоящих программ.
Давай представим, что мы собираем информацию о человеке. У человека есть имя, возраст, рост, любимый цвет. Как нам хранить всё это вместе? Можно сделать несколько переменных:
let name = "Аня";
let age = 14;
let height = 165;
let favoriteColor = "синий";
Но что, если у нас 100 человек? Тогда нам понадобится 400 переменных! Это неудобно. Именно здесь на помощь приходят объекты.
Объект — это как папка с документами. В папке лежат разные листочки, на каждом написано что-то своё: "Имя", "Возраст", "Любимый цвет". В программировании эти листочки называются свойствами.
Посмотри, как красиво выглядит объект:
let person = {
name: "Аня", // свойство "name" со значением "Аня"
age: 14, // свойство "age" со значением 14
height: 165, // свойство "height" со значением 165
favoriteColor: "синий" // свойство "favoriteColor" со значением "синий"
};
Видишь? Всё, что относится к Ане, собрано в одном месте. Это гораздо удобнее!
Как устроен объект?
Объект создаётся с помощью фигурных скобок {}. Внутри скобок мы пишем свойства через запятую. Каждое свойство состоит из:
- Ключа (имени свойства) — например,
name - Двоеточия — разделителя
- Значения — того, что хранится в свойстве
💡 Аналогия из жизни: Представь, что объект — это анкета. В анкете есть поля: "Имя", "Возраст", "Хобби". Это ключи. А ответы, которые ты вписываешь — это значения.
Значением может быть что угодно: число, строка, массив, другой объект и даже функция (но об этом позже).
Создаём первый объект
Давай создадим объект, который описывает твой любимый игровой персонаж или героя фильма:
// Создаём объект "герой"
let hero = {
name: "Супермен", // строка
power: 95, // число (сила от 0 до 100)
isFlying: true, // логическое значение (умеет летать?)
weapons: ["лазер", "кулаки"], // массив (список оружия)
weakness: "криптонит" // строка (слабость)
};
Отлично! Теперь у нас есть объект hero с пятью свойствами. Как нам получить доступ к этим свойствам? Есть два способа:
Способ 1: Точечная нотация (через точку)
console.log(hero.name); // Выведет: "Супермен"
console.log(hero.power); // Выведет: 95
console.log(hero.isFlying); // Выведет: true
Просто пишем имя объекта, ставим точку и пишем имя свойства. Как будто открываем папку и достаём нужный листочек.
Способ 2: Квадратные скобки
console.log(hero["name"]); // Выведет: "Супермен"
console.log(hero["power"]); // Выведет: 95
Этот способ похож на работу с массивами, только вместо индекса мы используем строку с именем свойства. Зачем это нужно? Иногда имя свойства хранится в переменной:
let key = "power";
console.log(hero[key]); // Выведет: 95 (так как key = "power")
С точкой так не получится — hero.key будет искать свойство с именем "key", а не "power".
Изменяем объекты
Объекты — это изменяемые структуры. Мы можем менять их свойства, добавлять новые или удалять старые. Давай поиграем с нашим героем:
// Меняем существующее свойство
hero.power = 100; // Теперь сила 100 (максимум!)
console.log(hero.power); // 100
// Добавляем новое свойство
hero.team = "Лига Справедливости";
console.log(hero.team); // "Лига Справедливости"
// Удаляем свойство (с помощью оператора delete)
delete hero.weakness;
console.log(hero.weakness); // undefined (свойства больше нет)
Обрати внимание: когда мы удаляем свойство, оно просто исчезает. При попытке обратиться к нему мы получим undefined — специальное значение, означающее "ничего".
Объекты внутри объектов
Помнишь, я говорил, что значением может быть что угодно? Даже другой объект! Давай сделаем нашего героя более детальным:
let hero = {
name: "Супермен",
stats: { // объект внутри объекта
strength: 100,
speed: 95,
intelligence: 80
},
equipment: { // ещё один объект
suit: "красный",
cape: true,
gadgets: ["лазер", "рентгеновское зрение"]
}
};
Как получить доступ к вложенным свойствам? Просто используем точки несколько раз:
console.log(hero.stats.strength); // 100
console.log(hero.equipment.cape); // true
console.log(hero.equipment.gadgets[0]); // "лазер" (первый элемент массива)
Это как заглянуть в папку, потом в подпапку, потом достать конкретный файл.
Методы объектов — функции внутри объектов
У объектов могут быть не только данные, но и действия. В JavaScript функции, которые являются свойствами объекта, называются методами.
let hero = {
name: "Супермен",
power: 95,
// Метод — функция, которая живёт внутри объекта
attack: function() {
console.log("💥 " + this.name + " атакует с силой " + this.power + "!");
},
// Можно использовать короткую запись (ES6)
fly() {
console.log("🦸 " + this.name + " летит!");
}
};
// Вызываем методы
hero.attack(); // 💥 Супермен атакует с силой 95!
hero.fly(); // 🦸 Супермен летит!
Обрати внимание на слово this. this — это ссылка на сам объект. Когда мы пишем this.name, JavaScript понимает: "возьми свойство name у того объекта, которому принадлежит этот метод".
🧠 Важно: Если бы мы написали простоname(безthis), JavaScript бы искал переменную с таким именем, а не свойство объекта.
Перебор свойств объекта
Иногда нужно пройтись по всем свойствам объекта и что-то с ними сделать. Для этого есть специальный цикл for...in:
let student = {
name: "Петя",
grade: 7,
subject: "математика",
score: 4.5
};
// Перебираем все ключи объекта
for (let key in student) {
console.log("Ключ: " + key + ", Значение: " + student[key]);
}
// Выведет:
// Ключ: name, Значение: Петя
// Ключ: grade, Значение: 7
// Ключ: subject, Значение: математика
// Ключ: score, Значение: 4.5
Цикл for...in проходит по всем ключам объекта. Внутри цикла мы используем student[key], потому что key — это переменная, и мы не можем использовать точку.
Есть и другие способы получить ключи и значения:
// Object.keys() — возвращает массив ключей
console.log(Object.keys(student)); // ["name", "grade", "subject", "score"]
// Object.values() — возвращает массив значений
console.log(Object.values(student)); // ["Петя", 7, "математика", 4.5]
// Object.entries() — возвращает массив пар [ключ, значение]
console.log(Object.entries(student));
// [["name", "Петя"], ["grade", 7], ["subject", "математика"], ["score", 4.5]]
Проверка существования свойства
Как узнать, есть ли у объекта определённое свойство? Есть два способа:
let car = {
brand: "Tesla",
model: "Model S"
};
// Способ 1: оператор in
console.log("brand" in car); // true
console.log("year" in car); // false
// Способ 2: проверка на undefined
console.log(car.brand !== undefined); // true
console.log(car.year !== undefined); // false
Оператор in более надёжный, потому что если свойство существует, но его значение специально установлено в undefined, то второй способ может ошибиться.
Копирование объектов
Когда мы копируем объект, нужно быть осторожным! Если просто присвоить один объект другому:
let original = { name: "Аня", age: 14 };
let copy = original; // Это не копия, а ссылка!
copy.name = "Маша";
console.log(original.name); // "Маша" — оригинал тоже изменился!
Почему так? Потому что объекты хранятся по ссылке. Переменная original хранит не сам объект, а адрес в памяти, где он находится. Когда мы пишем copy = original, мы копируем адрес, и обе переменные указывают на один и тот же объект.
Чтобы создать настоящую копию, нужно использовать Object.assign() или spread-оператор (...):
// Способ 1: Object.assign
let original = { name: "Аня", age: 14 };
let copy1 = Object.assign({}, original);
copy1.name = "Маша";
console.log(original.name); // "Аня" — не изменилось!
// Способ 2: spread-оператор (современный)
let copy2 = { ...original };
copy2.name = "Катя";
console.log(original.name); // "Аня" — всё ещё "Аня"
Но это работает только для поверхностного копирования. Если внутри объекта есть другие объекты, они всё равно будут скопированы по ссылке. Для глубокого копирования нужно использовать специальные методы, например, JSON.parse(JSON.stringify(obj)).
Практический пример: игра "Герой и монстр"
Давай создадим мини-игру, используя объекты. У нас будет герой и монстр, они будут сражаться.
// Создаём объект "герой"
let hero = {
name: "Рыцарь",
health: 100, // здоровье
attackPower: 20, // сила атаки
defense: 10, // защита
// Метод для атаки
attack(target) {
let damage = this.attackPower - target.defense;
if (damage < 0) damage = 0; // защита может быть сильнее атаки
target.health -= damage;
console.log(this.name + " атакует " + target.name + " и наносит " + damage + " урона!");
console.log("У " + target.name + " осталось " + target.health + " здоровья.");
},
// Метод для лечения
heal(amount) {
this.health += amount;
console.log(this.name + " лечится на " + amount + " здоровья. Теперь здоровья: " + this.health);
}
};
// Создаём объект "монстр"
let monster = {
name: "Дракон",
health: 150,
attackPower: 15,
defense: 5,
attack(target) {
let damage = this.attackPower - target.defense;
if (damage < 0) damage = 0;
target.health -= damage;
console.log(this.name + " атакует " + target.name + " и наносит " + damage + " урона!");
console.log("У " + target.name + " осталось " + target.health + " здоровья.");
}
};
// Симуляция боя
console.log("⚔️ Бой начинается!");
hero.attack(monster); // Рыцарь атакует Дракона
monster.attack(hero); // Дракон атакует Рыцаря
hero.heal(15); // Рыцарь лечится
monster.attack(hero); // Дракон снова атакует
Видишь, как объекты помогают организовать код? Каждый персонаж — это отдельный объект со своими свойствами (здоровье, сила) и методами (атака, лечение).
Когда использовать объекты?
Объекты идеально подходят, когда нужно объединить связанные данные в одну сущность. Вот несколько примеров из реальной жизни:
- Пользователь: имя, возраст, email, пароль, дата регистрации
- Товар в магазине: название, цена, количество на складе, описание
- Игровой персонаж: имя, уровень, здоровье, инвентарь, навыки
- Книга в библиотеке: автор, название, год издания, жанр
- Настройки приложения: язык, тема, размер шрифта, уведомления
Если у тебя есть набор данных, которые относятся к одному и тому же "предмету" — смело используй объект!
Распространённые ошибки
Давай разберём типичные ошибки, которые допускают новички:
- Забыть запятую между свойствами — это вызовет синтаксическую ошибку.
- Использовать точку с запятой вместо запятой — тоже ошибка.
- Пытаться обратиться к несуществующему свойству — получишь
undefined, программа не сломается, но может работать неправильно. - Путать
=и==— при присваивании используем один знак равенства. - Забыть
thisвнутри методов — если ты пишешьnameвместоthis.name, JavaScript будет искать переменнуюname, а не свойство объекта.
// Пример ошибки №5
let obj = {
name: "Тест",
showName: function() {
console.log(name); // Ошибка! name не определена
console.log(this.name); // Правильно: "Тест"
}
};
obj.showName();
Практические задания
А теперь давай закрепим знания на практике. Попробуй выполнить эти задания самостоятельно. Если что-то не получается — перечитай урок или попроси помощи у преподавателя.
Задание 1: "Мой профиль"
Создай объект myProfile, который описывает тебя. Включи следующие свойства:
firstName— имя (строка)lastName— фамилия (строка)age— возраст (число)hobbies— массив хобби (минимум 3)isStudent— учишься ли ты (логическое значение)contacts— объект с контактами (email, телефон)
После создания выведи в консоль фразу: "Меня зовут [имя] [фамилия], мне [возраст] лет. Мои хобби: [хобби через запятую]."
// Пример решения (твой вариант может отличаться)
let myProfile = {
firstName: "Иван",
lastName: "Петров",
age: 14,
hobbies: ["программирование", "футбол", "чтение"],
isStudent: true,
contacts: {
email: "ivan@example.com",
phone: "+7-123-456-78-90"
}
};
console.log("Меня зовут " + myProfile.firstName + " " + myProfile.lastName +
", мне " + myProfile.age + " лет. Мои хобби: " + myProfile.hobbies.join(", ") + ".");
Задание 2: "Калькулятор счёта"
Создай объект restaurantBill, который представляет счёт в ресторане. У объекта должны быть:
items— массив объектов, каждый объект — это блюдо: название и ценаtipPercent— процент чаевых (число, например, 10 для 10%)getTotal— метод, который вычисляет общую сумму (сумма всех блюд + чаевые)addItem— метод, который добавляет новое блюдо в массив
Добавь минимум 3 блюда, затем вызови метод getTotal и выведи результат.
// Пример решения
let restaurantBill = {
items: [],
tipPercent: 10,
addItem: function(name, price) {
this.items.push({ name: name, price: price });
},
getTotal: function() {
let sum = 0;
for (let item of this.items) {
sum += item.price;
}
let tip = sum * this.tipPercent / 100;
return sum + tip;
}
};
// Добавляем блюда
restaurantBill.addItem("Пицца", 500);
restaurantBill.addItem("Салат", 200);
restaurantBill.addItem("Сок", 100);
console.log("Общий счёт с чаевыми: " + restaurantBill.getTotal() + " рублей");
Задание 3: "Библиотека книг" (сложное)
Создай объект library, который управляет коллекцией книг. У объекта должны быть:
books— массив книг (каждая книга — объект с полями: title, author, year, isRead)addBook— метод для добавления новой книгиmarkAsRead— метод, который принимает название книги и меняетisReadна truelistUnread— метод, который выводит список всех непрочитанных книгgetStats— метод, который возвращает строку: "Всего книг: [N], прочитано: [M], не прочитано: [K]"
Добавь 4-5 книг, отметь некоторые как прочитанные, затем выведи статистику и список непрочитанных.
// Пример решения
let library = {
books: [],
addBook: function(title, author, year) {
this.books.push({
title: title,
author: author,
year: year,
isRead: false
});
},
markAsRead: function(title) {
for (let book of this.books) {
if (book.title === title) {
book.isRead = true;
console.log("Книга \"" + title + "\" отмечена как прочитанная.");
return;
}
}
console.log("Книга \"" + title + "\" не найдена.");
},
listUnread: function() {
console.log("Непрочитанные книги:");
for (let book of this.books) {
if (!book.isRead) {
console.log("- " + book.title + " (" + book.author + ", " + book.year + ")");
}
}
},
getStats: function() {
let total = this.books.length;
let read = 0;
for (let book of this.books) {
if (book.isRead) read++;
}
let unread = total - read;
return "Всего книг: " + total + ", прочитано: " + read + ", не прочитано: " + unread;
}
};
// Добавляем книги
library.addBook("Гарри Поттер", "Дж.К. Роулинг", 1997);
library.addBook("Властелин колец", "Дж.Р.Р. Толкин", 1954);
library.addBook("Маленький принц", "Антуан де Сент-Экзюпери", 1943);
library.addBook("1984", "Джордж Оруэлл", 1949);
// Отмечаем прочитанные
library.markAsRead("Гарри Поттер");
library.markAsRead("Маленький принц");
// Выводим статистику и список
console.log(library.getStats());
library.listUnread();
Заключение
Поздравляю! 🎉 Ты только что изучил одну из самых важных тем в JavaScript — объекты. Теперь ты умеешь: