Знаете ли вы, что Javascript на самом деле не является языком на основе классов, а на высоком уровне это язык на основе прототипов?

Сказав это, что такое прототип в javascript?

Давайте создадим простой объект Car

const Car = { name: 'Ferrari' }

Если мы попытаемся получить доступ к объекту Car в консоли, он предоставит вам доступ к определенным свойствам, как показано ниже.

Здесь мы создали Car объект всего с одним свойством name. Но на снимке экрана показан доступ ко многим другим свойствам и методам, которые мы на самом деле не создавали. Они доступны нам, и вы можете использовать их так же, как ваши собственные свойства и методы.

Почти все в Javascript - это объект. И у каждого такого объекта есть свой прототип. Теперь давайте посмотрим на прототип нашего Car объекта.

Вы можете получить доступ к прототипу любым из следующих способов:

// старый способ

Car.__proto__ (__proto__ устарел и больше не рекомендуется)

// новый путь

Object.getPrototypeOf(Car)

А вот как бы это выглядело,

Подобным образом объект-прототип объекта также может иметь прототипы.

Что ж, теперь мы знаем, что такое прототипы. Давайте посмотрим, как это связано с миксинами.

В Javascript может быть только один [[prototype]] для объекта, что означает, что мы можем наследовать только от одного объекта.

Но иногда наше приложение может потребовать расширения более одного. Попробуем разобраться в этом на примере.

Скажем, например, у нас есть два класса User и CleanRoom. Предположим, нам нужно добавить CleanRoom функциональность к User, чтобы пользователи могли убирать комнату по запросу. Здесь на сцену выходит концепция под названием миксины.

Миксины в Javascript

Mixin - это общий термин объектно-ориентированного программирования - это класс, содержащий методы, которые могут использоваться другими классами без необходимости наследовать от него.

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

Чтобы прояснить ситуацию, возьмем тот же пример, приведенный выше, и посмотрим, как он реализуется на практике.

// mixin
let cleanRoomMixin = {
     cleanRoom() {
     alert(`Hello ${this.name}, your room is clean now`);
},
sayBye() {
     alert(`Bye ${this.name}`);
}
};

// usage:
class User {
     constructor(name) {
          this.name = name;
     }
}

// copy the methods
Object.assign(User.prototype, cleanRoomMixin);

// now User can clean the room
new User("Max").cleanRoom(); // Hello Max, your room is clean now!

В приведенном выше коде мы создали cleanRoomMixin, в котором определены два действия: cleanRoom и sayBye. У нас также есть объект User с простым конструктором для инициализации свойства name.

Теперь, чтобы привязать cleanRoom действие к User объекту, мы используем метод Object.assign и привязываем миксин к прототипу объекта. Таким образом, мы можем независимо использовать любое действие в разных объектах.

Здесь нет наследования, только простое копирование метода. Проще говоря, миксины помогают создавать автономные объекты с похожими функциями.

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

Круто, вот и все миксины. Разве это не легко и понятно?

Если у вас есть предложения, вам нужна помощь / сомнения или вы хотите обсудить больше по этой теме, напишите мне на [email protected]. Я также хотел бы связаться со всеми вами в Linkedin.