Имеется ли в JavaScript понятие 'интерфейса', как в Java?

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

JavaScript не поддерживает интерфейсы в том ключе, в каком они представлены в Java. Впрочем, можно искусственно воссоздать интерфейсы, применяя синтаксис классов и определяя методы, которые выкидывают исключения:

JS
Скопировать код
class MyInterface {
  methodA() { throw new Error("Этот метод необходимо реализовать!"); }
  methodB() { throw new Error("Этот метод необходимо реализовать!"); }
}

class MyClass extends MyInterface {
  methodA() {
    // Реализация метода
  }
  methodB() {
    // Реализация метода
  }
}

Такой подход необходим для реализации методов MyClass, которые объявлены в MyInterface, подобно тому, как интерфейсы определяют договор на методы.

Кинга Идем в IT: пошаговый план для смены профессии

Поведение, свойственное интерфейсам, в JavaScript

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

Проверка присутствия метода

Для предотвращения ошибок выполнения кода, важно убедиться в наличии метода, перед его использованием. Для этого подходит оператор typeof:

JS
Скопировать код
if (typeof obj.mammoth_hunt === 'function') {
  obj.mammoth_hunt();
} else {
  throw new Error("Метод mammoth_hunt не обнаружен!");
}

Да и неперечисляемые свойства можно проверить с использованием Object.defineProperty:

JS
Скопировать код
Object.defineProperty(MyClass.prototype, 'mammoth_hunt', {
  value: function() {
    // Реализация охоты на мамонта
  },
  enumerable: false
});

Разработка функции валидации

Модификация Object.prototype является рискованной, так как могут возникнуть коллизии со второстепенными действиями в других участках программы. В качестве замены можно создать функцию для проверки реализации интерфейса:

JS
Скопировать код
function implementsInterface(obj, methods) {
  return methods.every(method => typeof obj[method] === 'function');
}

Здесь every проверяет наличие каждого метода в объекте.

Собственная реализация проверки интерфейса

В случае отсутствия ключевого слова implements можно проверить реализацию интерфейса в объекте вручную:

JS
Скопировать код
Object.implement = function (obj, methods) {
  return implementsInterface(obj, methods);
};

Это не вводит строгую типизацию, но обеспечивает определенную проверку.

Конструкторы и прототипы

Применение функций-конструкторов и прототипов позволяет воссоздать поведение интерфейсов:

JS
Скопировать код
function Circle() {
  // Определение свойств круга
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.draw = function() {
  // Здесь должна быть реализация рисования круга
};

Это гарантирует, что любой класс, производный от Shape, имеет свою версию метода draw.

Визуализация

JavaScript можно представить как универсального исполнителя без специализированных подходов:

Markdown
Скопировать код
Объекты JavaScript (🔨): [Function, Object, Class]
Интерфейс Java (📜): [Определяет структуру]

TypeScript здесь выступает в качестве профессионального архитектора:

typescript
Скопировать код
interface Blueprint {
  buildPartA(): void;
  buildPartB(): void;
};

class ConstructionKit implements Blueprint {
  buildPartA() { /* Начало работ */ }
  buildPartB() { /* не забывайте про защиту проекта */ }
}

// Теперь возможно строить изысканные новостройки 🌆

➡️ TypeScript предлагает JavaScript необходимые чертежи, которые до этого ему не хватало.

Симуляция интерфейсов в JavaScript

Несмотря на непосредственное отсутствие интерфейсов в JavaScript, реально их эмулировать путем использования различных паттернов и методик.

Создание объектов для сигнатур методов

Объект может послужить шаблоном для сигнатур методов, выступаю в роли интерфейса:

JS
Скопировать код
const DrawableInterface = {
  draw: function() { throw new Error('Необходима реализация метода draw.'); }
};

Воссоздание интерфейсов с применением шаблонов

Использование объекта-интерфейса в качестве основы для прототипа конструктора позволяет придерживаться определенного контракта:

JS
Скопировать код
function DrawableObject() {
  Object.assign(this, DrawableInterface);
}

// Теперь понятно что ожидается от объектов.

Задание прототипов для требований интерфейса

Назначение прототипов мотивирует разработчиков на реализацию необходимых методов, как если бы это был интерфейс:

JS
Скопировать код
function Square() {
  // Свойства квадрата
}

Square.prototype = Object.create(DrawableInterface);
Square.prototype.draw = function() {
  // Отрисовка квадрата
};

Правильное использование гибкости JavaScript

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

Полезные материалы

  1. Классы в JavaScript | MDN — углубленное изучение классов и имитации интерфейсов в JavaScript.
  2. TypeScript: Документация — Интерфейсы — преимущества TypeScript для работы со структурами.
  3. Интерфейсы против типов в TypeScript на Stack Overflow — интересные дебаты о TypeScript.
  4. Понимание типизации в TypeScript — подробный разбор системы типов в TypeScript.
  5. Глава о Классах из ES6 — введение в классы и наследование в ES6.
  6. Спецификация ECMAScript 2015 (ES6) — официальное описание определений классов в ES6.
Свежие материалы