question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Possible to use bare classes as mixins?

See original GitHub issue

For example,

Suppose I have a class,

class Transformable { ... }

I can easily extend that,

class ThreeDeeObject extends Transformable {}

Now suppose I want ThreeDeeObject to have characteristics of Transformable, EventEmitter, and TreeNode, which let’s suppose are all plain classes just like Transformable,

class EventEmitter { ... }
class TreeNode { ... }

Would it be possible to make the mixwith API accept these plain classes as arguments to with(), so that

class ThreeDeeObject extends mix(/* class {} */).with(Transformable, EventEmitter, TreeNode) { ... }

?

The reason I ask is because I also like the option of extending one of those classes directly, not being limited to using them as mixins. For example:

class ThreeDeeObject extends mix(/* class {} */).with(Transformable, EventEmitter, TreeNode) { ... }
class SomethingElse extends EventEmitter { ... } // extend EventEmitter directly.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
machineghostcommented, Sep 15, 2016

Can I suggest that you put this workaround:

class ClassWithMixinButNoParent extends Mixin(Object);

somewhere in the documentation for mixwith (or in the excellent blog post which spawned it … or both)?

I think it’s an essential pattern for a significant percentage of people who want to use mix-ins (not every class has a parent), and it’d be nice if others didn’t have to dig through the issues to find it.

P.S. Thanks for pioneering this technique; IMHO it should be the one true pattern for doing mix-ins in JS.

1reaction
trusktrcommented, Jul 18, 2016

After thinking about #14 (and not liking the implementation, though I like the outer API), I think what I’m going to do is try an onion-like approach like what you’ve got (instead of branching), except that I want to be able to pass vanilla classes (not parameterized class factories) into the multiple() (or mix().with()) call.

If possible, what I’d to do is take the vanilla classes passed as input, then build internal class factories that accept parameterized superclasses, then use those class-factories internally in the implementation so that the end user does have to even know about the class-factory pattern.

So, the idea is this, if possible:

class Foo {}
class Bar extends Foo {}
(new Bar) instanceof Foo // true

let Klass = multiple(Foo) // take note!
class Baz extends Klass {}
(new Baz) instanceof Klass // true
(new Baz) instanceof Foo // true (is this possible?)

class Lorem {}
let Clazz = multiple(Foo, Lorem) // take note!
class Ipsum extends Clazz {}
(new Ipsum) instanceof Clazz // true
(new Ipsum) instanceof Foo // true (is this possible?)
(new Ipsum) instanceof Lorem // true (is this possible?)

This way (if possible) plain vanilla classes remain vanilla classes that don’t have to be used with any extra patterns, so the end class designer does not need to use a mixin pattern (class factories), and needs not make any API calls when extending a single class (unlike currently, where a class-factory requires an API call even if extending from only a single mixin class). For example, if I just want to extend Lorem from above, I only need to use plain ES6 class syntax:

class Something extends Lorem {}

I would not have to do any of the following just to extend a single class:

class Something extends Lorem(class {}) {}
class Something extends mix(class {}).with(Lorem) {}
class Something extends multiple(Lorem) {}

So, basically,

// import ES6 classes
import Foo from './Foo'
import Lorem from './Lorem'

// --- extend one class:
class Something extends Lorem {}

// --- extend more than one class:
class Something extends mix(Foo).with(Lorem) {}
// or
class Something extends multiple(Foo, Lorem) {}

// --- instanceof:
(new Something) instanceof Lorem // true in all cases

Alright, I’m going to go try and implement it…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Provide mixins for list-bare and list-inline · Issue #419 - GitHub
By extracting the CSS of the list-bare and list-inline to mixins, we can give users the possibility to use just the mixins in...
Read more >
Is there a way to generate interface from class in D using mixin ...
It is possible to write such mixin but that will create a circular dependency issue - being able to generate an interface but...
Read more >
Mixin - Wikipedia
In object-oriented programming languages, a mixin (or mix-in) is a class that contains methods for use by other classes without having to be...
Read more >
Composing Angular Components with Typescript Mixins
The way Mixins are created with Typescript is simple: we define a function that takes as argument a class and extend the newly...
Read more >
Mixins or composition? | Pages from the fire
Composition is great for handling complex functionality by insulating individual parts into their own classes and just exposing the bare ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found