JavaScript с нуля - [42]

Шрифт
Интервал

Создание пользовательских объектов

Работа с обобщенным объектом 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;

}

В этом случае его повторение ни к чему, следовательно, нам стоит сделать его общедоступным и избежать повторения. И как же?

Что ж… Для этого есть прямой путь, а именно создание промежуточного родительского объекта, содержащего общие свойства. В свою очередь, наши дочерние объекты смогут наследовать от этого родительского объекта вместо наследования напрямую от Object. Для большей конкретики мы создадим объект person, содержащий свойство getName. Наши объекты funnyGuy, theDude и detective станут наследниками person. Упорядоченная таким образом структура обеспечит, чтобы все свойства, требующие повторения, были повторены, а требующие совместного использования использовались совместно. Лучше понять все сказанное поможет рис. 18.5, где эти действия изображены наглядно.

Рис. 18.5. Добавление промежуточного объекта person со свойством (теперь используемым совместно) getName

Заметьте, что теперь person стал частью цепочки прототипов, удачно расположившись между Object.prototype и нашими дочерними объектами. Как же это делается? Один из подходов мы уже видели ранее, и в нем мы опираемся на Object.create. При использовании Object.create мы можем указать объект, на основе которого требуется создать новый объект. Например:

let myObject = Object.create(fooObject);

Когда мы это делаем, за кадром происходит следующее: прототип нашего объекта myObject теперь будет fooObject. При этом он становится частью цепочки прототипов. Теперь, когда мы сделали крюк и расширили наше понимание Object.create, освоив содержание этой главы. Давайте вернемся к изначальному вопросу о том, как же именно наши объекты funnyGuy, theDude и detective наследуют от person.

Код, осуществляющий все это, будет таким:

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

Такая возможность создавать промежуточные объекты, помогающие разделять функциональность кода, является мощным инструментом. Она повышает эффективность создания объектов и добавления в них функциональности. Неплохо, правда?

Ключевое слово this

В предыдущих фрагментах кода вы могли заметить использование ключевого слова this, особенно в случае с объектом person, где мы задействовали его для обращения к свойствам, созданным в его потомках, а не к его собственным. Давайте вернемся к этому объекту, а в частности к его свойству getName:


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

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