Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript进行合成和混合_Javascript_Multiple Inheritance - Fatal编程技术网

使用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

我正在学习Javascript中的合成。所以我想问一下,这是否是正确的做事方式

我做了一些类似这样的练习:

    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()
    创建实例。(迭代属性描述符也是如此。)
  • 您可以使用对
    Object.create()
    的一系列迭代调用来创建Duck原型,而不是迭代扩展基类
  • 您可以使用辅助控制器类控制其他行为,而不是将行为直接组合到基中
  • 您可以只处理带有数据的普通对象,并将对象传递给希望对象具有某些属性的函数,以便执行操作。(有趣的是,被称为“ducktyping”)我承认这不是真正的混入,只是调用函数,但如果它实际上完成了同样的事情
  • 可能还有一些我现在真的想不起来的。这都是把一系列的行为粘在一些基本的东西上

您运行了吗?非常感谢您详细的回答。这对我帮助很大。祝您有个美好的一天!