nzakas / understandinges6

Content for the ebook "Understanding ECMAScript 6"
5.45k stars 796 forks source link

Mixins could be done better #412

Closed elibarzilay closed 6 years ago

elibarzilay commented 6 years ago

Mixins are described in a way that is a bit ugly, since the example uses prototype which is depending on how classes are implemented. It's something that is unlikely to break, but there's a way to do the same without going down to the plumbing levels:

  let SerializableMixin = (C) => class Serializable extends C {
    serialize() { return JSON.stringify(this); }
  };
  let AreaMixin = (C) => class Areable extends C {
    getArea() { return this.length * this.width; }
  };
  class Square extends SerializableMixin(AreaMixin(Object)) {
    constructor(length) {
      super();
      this.length = length;
      this.width = length;
    }
  }
  let x = new Square(3);
  console.log(x.getArea());     // 9
  console.log(x.serialize());   // "{\"length\":3,\"width\":3}"

[Disclaimer: this is the way it's done in some languages; I thought that someone must have done it in JS too, and sure enough, someone did.]

nzakas commented 6 years ago

That’s pretty cool. A difference between this and what I have in the book is that this creates uses inheritance as the primary way of doing mixins (in that each if your classes extends another to gain its functionality) whereas mine is attempting to show that you can avoid using inheritance (outside of the mixin function) to gain new functionality.

Thanks for the feedback.

elibarzilay commented 6 years ago

@nzakas, yes --- and this is a good thing to mention because (a) it uses the proper inheritance so it can survive a possible future revision of JS that might invalidate the direct approach (unlikely) or that will add more benefits to the "proper" class way; and (b) it's a common pattern in some functional languages, so it's good to let JS people know about it too...