Он сделал более или менее то, что вы ожидали? Тогда, конечно, это a правильный способ сделать это, что бы здесь ни означало «правильный».
Мне кажется, что он делает то, что должен был делать, когда я вставляю его в консоль. Я не могу сказать больше о вашем коде, в частности, потому что я не уверен, какую конкретную область он пытается смоделировать, за исключением, может быть, разбиения Уток на атомарные части.
Однако, если вы собираетесь сделать это таким образом, я бы лично предпочел использовать объект params вместо простого изменения сигнатуры конструктора, например, с помощью AnimalsWithWings
. Таким образом, порядок дополнительной параметризации не зависит от порядка, в котором применялись миксины, что я бы назвал сюрпризом. Сюрпризы плохие.
const AnimalsWithWings = superclass => class extends superclass {
// Everyone receives the same `params` object.
// They only take what they know about, and ignore the rest.
constructor(params) {
super(params);
Object.assign(this, { Feathers: params.Feathers });
}
}
Еще более личное мнение, я бы назвал их WithDiving
и WithWings
вместо этого, просто чтобы сохранить несколько непротиворечивую схему именования и чтобы лучше понять, что это модификаторы, а не "настоящие" базовые классы.
Ваш код оседлал каждого Утка с прототипами длиной в 4 прототипа, но как угодно. Если это каким-то образом становится проблемой производительности, то вы можете создать служебную функцию для оптимизации процесса смешивания или что-то еще. Сгладить прототипы, может быть.
Ваш код делает также позволяет называть super.method()
в методах, хотя это спорно, следует ли вам когда-либо использовать, что в Mixin вообще. Я бы сказал, что вы не должны этого делать, если только вы не хотите, чтобы ваши миксины неявно зависели друг от друга, что является сюрпризом.
Есть много других способов делать миксин тоже.
- Вы можете создать служебную функцию, чтобы объединить все прототипы в один новый и вернуть базовый класс из того, который вы расширяете. (Просто выполняйте итерацию дескрипторов свойств, а не просто используйте
Object.assign()
при выполнении этого выравнивания, если вы хотите правильно обрабатывать такие вещи, как get
/ set
методы доступа и т. Д.)
- Вы можете отказаться от классов и просто напрямую создавать объекты-прототипы и использовать
Object.create()
для создания экземпляров. (то же самое с итерацией дескрипторов свойств.)
- Вы можете создать прототип Duck, используя несколько итеративных вызовов
Object.create()
вместо итеративно расширяющихся базовых классов.
- Вы можете управлять дополнительным поведением с помощью вспомогательных классов контроллеров вместо того, чтобы составлять поведение непосредственно в базу.
- Вы могли бы иметь дело просто с простыми объектами с данными и передавать объекты функциям, которые ожидают, что объект будет иметь определенные свойства для того, чтобы что-то делать. (Забавно, это называется «типизацией по утке») Я позволю себе сказать, что это на самом деле не миксины, а просто вызов функций, но если это выполнит то же самое в действительности ...
- Вероятно, куча других, о которых я сейчас не могу думать. Это все приклеивает наборы поведения к какой-то базовой вещи.