Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Наследование JS: Погружаясь в классы

Наследование классов – механизм, позволяющий создавать классы (говорят подклассы) на основе других классов (называемых базовыми или суперклассами). Подклассы в таком случае "наследуют" структуру базовых классов, то есть получают возможность использовать всё, что определено в базовом классе.

Механизм наследования – сложная система. Поэтому изучаться он будет в несколько приёмов, на протяжении всего курса. Кроме того, не забываем что говоря про классы в JavaScript, мы на самом деле говорим про прототипы.

Рассмотрим наследование на примере структуры HTML. Каждый тег в HTML по своему уникален. С другой стороны, все они имеют общие атрибуты и некоторые другие характеристики. Попробуем отобразить это с помощью иерархии классов.

// Базовый класс для всех тегов. Умеет работать с атрибутами.
class HTMLElement {
  constructor(attributes = {}) {
    this.attributes = attributes;
  }

  setAttribute(key, value) {
    this.attributes[key] = value;
  }

  getAttribute(key) {
    return this.attributes[key];
  }

  getTextContent() {
    return this.body;
  }

  setTextContent(body) {
    this.body = body;
  }

  stringifyAttributes() {
    // build: key="value" key2="value2"
  }
}

Конкретные элементы, представленные тегами в HTML, наследуют этот класс:

// Anchor – это ссылка. Класс HTMLAnchorElement описывает тег "a".
// Наследование выполняется через ключевое слово extends
class HTMLAnchorElement extends HTMLElement {
  toString() {
    // Родительский метод
    const attrLine = this.stringifyAttributes();
    // Родительский метод
    const body = this.getTextContent();
    return `<a${attrLine}>${body}</a>`;
  }
}

Наследование записывается так: A extends B. Эта запись означает, что класс A наследует класс B. Теперь посмотрим, как работает наследование:

// Конструктор родителя
const anchor = new HTMLAnchorElement({ href: 'https://ru.hexlet.io' });
anchor.setTextContent('Hexlet');
console.log(`Anchor: ${anchor}`); // toString() вызывается автоматически
// => Anchor: <a href="https://ru.hexlet.io">Hexlet</a>

Внутри HTMLAnchorElement нет определения конструктора, но благодаря наследованию, этот класс имеет доступ ко всем свойствам суперкласса. JavaScript вызывает их автоматически при обращении к ним. В свою очередь, внутри toString() вызываются методы, которых нет в текущих классах, поэтому они также берутся из родительского класса.

Цепочка наследования

В отличие от интерфейсов, наследование классов в JavaScript – одиночное. Другими словами, наследоваться можно только от одного класса. Точно так же как и в Java. Множественное наследование в этих языках было убрано специально, из-за его высокой сложности и проблем, которые оно добавляет (например, коллизии методов и свойств). С другой стороны, сама по себе цепочка наследования может быть сколь угодно глубокой:

class D {}
class C extends D {}
class B extends C {}
class A extends B {}

Оператор проверки типа

Оператор instanceof учитывает классы из цепочки наследования прототипов:

const anchor = new HTMLAnchorElement();
if (anchor instanceof HTMLElement) {
    console.log('!!!');
}
// => !!!

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


Дополнительные материалы

  1. Наследование (Wiki)

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
1 июня 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
1 июня 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
1 июня 16 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»