JavaScript с нуля
- Автор: Кирупа Чиннатамби
- Жанр: Образование
- Дата выхода: 2021
- Цикл: Библиотека программиста
Читать книгу "JavaScript с нуля"
Создание пользовательских объектов
Работа с обобщенным объектом Object и добавление в него свойств служит определенной цели, но вся его прелесть быстро исчезает, когда мы создаем много одинаковых в основе объектов. Взгляните на этот фрагмент:
let funnyGuy = {
firstName: "Conan",
lastName: "O'Brien",
getName: function () {
return "Name is: " + this.firstName + " " + this.lastName;
}
};
let theDude = {
firstName: "Jeffrey",
lastName: "Lebowski",
getName: function () {
return "Name is: " + this.firstName + " " + this.lastName;
}
};
let detective = {
firstName: "Adrian",
lastName: "Monk",
getName: function () {
return "Name is: " + this.firstName + " " + this.lastName;
}
};
Этот код создает объект funnyGuy и вводит два новых очень похожих на него объекта theDude и detective. Наша визуализация всего этого теперь будет выглядеть, как показано на рис. 18.4.
Рис. 18.4. Каждый вновь созданный объект расширяется от Object.prototype
На первый взгляд кажется, что здесь многовато повторений. Каждый из только что созданных объектов содержит свою собственную копию свойств firstName, lastName и getName. Итак, все же повторение — это не всегда плохо. Да, есть противоречие тому, что я утверждал ранее, но дайте-ка я все объясню. В случае с объектами нужно выяснить, какие свойства имеет смысл повторять, а какие нет. В нашем примере свойства firstName и lastName будут, как правило, уникальны для каждого объекта, а значит, это повторение имеет смысл. А вот свойство getName хоть и выступает в роли помощника, но не содержит ничего, что отдельный объект мог бы определить уникально:
getName: function () {
return "Name is: " + this.firstName + " " + this.lastName;
}
В этом случае его повторение ни к чему, следовательно, нам стоит сделать его общедоступным и избежать повторения. И как же?
Что ж… Для этого есть прямой путь, а именно создание промежуточного
Рис. 18.5. Добавление промежуточного объекта person со свойством (теперь используемым совместно) getName
Заметьте, что теперь person стал частью цепочки прототипов, удачно расположившись между Object.prototype и нашими дочерними объектами. Как же это делается? Один из подходов мы уже видели ранее, и в нем мы опираемся на Object.create. При использовании Object.create мы можем указать объект, на основе которого требуется создать новый объект. Например:
let myObject = Object.create(fooObject);
Когда мы это делаем, за кадром происходит следующее:
Код, осуществляющий все это, будет таким:
let person = {
getName: function () {
return "The name is " + this.firstName + " " + this.lastName;
}
};
let funnyGuy = Object.create(person);
funnyGuy.firstName = "Conan";
funnyGuy.lastName = "O'Brien";
let theDude = Object.create(person);
theDude.firstName = "Jeffrey";
theDude.lastName = "Lebowski";
let detective = Object.create(person);
detective.firstName = "Adrian";
detective.lastName = "Monk";
Принцип работы цепочки прототипов позволяет нам вызывать getName для любого из наших объектов funnyGuy, theDude или detective, что приведет к ожидаемому результату:
detective.getName(); // Имя Adrian Monk
Если мы решим расширить объект person, то достаточно сделать это всего один раз, и это также отразится на всех наследующих от него объектах, не требуя дополнительного повторения. Предположим, мы хотим добавить метод getInitials, возвращающий первую букву из имени и фамилии:
let person = {
getName: function () {
return "The name is " + this.firstName + " " + this.lastName;
},
getInitials: function () {
if (this.firstName && this.lastName) {
return this.firstName[0] + this.lastName[0];
}
}
};
Мы добавляем метод getInitials в объект person. Чтобы использовать этот метод, можем вызвать его для любого объекта, расширяющего person, например funnyGuy:
funnyGuy.getInitials(); // CO
Такая возможность создавать промежуточные объекты, помогающие разделять функциональность кода, является мощным инструментом. Она повышает эффективность создания объектов и добавления в них функциональности. Неплохо, правда?