使用JavaScript进行合成和混合
我正在学习Javascript中的合成。所以我想问一下,这是否是正确的做事方式 我做了一些类似这样的练习:使用JavaScript进行合成和混合,javascript,multiple-inheritance,Javascript,Multiple Inheritance,我正在学习Javascript中的合成。所以我想问一下,这是否是正确的做事方式 我做了一些类似这样的练习: class Animal { // constructor() { // } eat = () => { console.log("this creature is eating"); } } const AnimalsWithWings = superclass => class extends superclass
class Animal {
// constructor() {
// }
eat = () => {
console.log("this creature is eating");
}
}
const AnimalsWithWings = superclass => class extends superclass {
constructor(Feathers, ...args) {
super(...args);
Object.assign(this, { Feathers });
}
}
const CanDive = superclass => class extends superclass {
// constructor( ...args) {
// super(...args);
// }
dive = () => {
console.log("Can Dive");
}
}
class Duck extends AnimalsWithWings(CanDive(Animal)) {
constructor(eats, ...args) {
super(...args);
Object.assign(this, { eats });
}
}
const duffy = new Duck("watermelon", true);
console.log(duffy);
duffy.dive();
duffy.eat()
我仍在学习过程中,所以我只需要一些指导。它是否达到了您的预期?当然,这是一种正确的方法,不管这里的“正确”是什么意思 在我看来,当我将它弹出到控制台时,它做了它应该做的事情。我真的不能说更多关于你的代码,因为我不确定它试图建模的是什么具体领域,除了可能将鸭子分解成原子碎片 但是,如果您打算这样做,我个人更喜欢使用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个原型,但是,呃,不管怎样。如果它以某种方式成为一个性能问题,那么您可以创建一个实用函数来优化mixin进程或其他东西。可能是把原型弄平
您的代码也允许您在方法中调用super.method()
,尽管您是否应该在mixin中使用它仍有争议。我认为你不应该这样做,除非你想让你的混血儿彼此依赖,这是一个惊喜
还有很多其他的混合方式
- 您可以创建一个实用函数,将所有原型展平为一个新原型,并从扩展的原型返回一个基类。(如果您想正确处理诸如
/get
访问器等问题,请确保在执行展平时迭代属性描述符,而不仅仅使用set
)Object.assign()
- 您可以避开类,直接创建原型对象,然后使用
创建实例。(迭代属性描述符也是如此。)Object.create()
- 您可以使用对
的一系列迭代调用来创建Duck原型,而不是迭代扩展基类Object.create()
- 您可以使用辅助控制器类控制其他行为,而不是将行为直接组合到基中
- 您可以只处理带有数据的普通对象,并将对象传递给希望对象具有某些属性的函数,以便执行操作。(有趣的是,被称为“ducktyping”)我承认这不是真正的混入,只是调用函数,但如果它实际上完成了同样的事情
- 可能还有一些我现在真的想不起来的。这都是把一系列的行为粘在一些基本的东西上