Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here

universal-mixin

A mixin usable for both generic objects and decorators.

Subscribe to updates I use universal-mixin


Statistics on universal-mixin

Number of watchers on Github 56
Number of open issues 0
Average time to close an issue about 23 hours
Main language JavaScript
Average time to merge a PR less than a minute
Open pull requests 0+
Closed pull requests 0+
Last commit over 3 years ago
Repo Created almost 5 years ago
Repo Last Updated over 2 years ago
Size 464 KB
Organization / Authorwebreflection
Contributors2
Page Updated
Do you use universal-mixin? Leave a review!
View universal-mixin activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating universal-mixin for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

universal-mixin build status

Inspired by Reginald Braithwaite proposal in his Using ES.later Decorators as Mixins post, and discussed with both Reginald and Addy Osmani in the gist related to Addy's Exploring ES2016 Decorators post, this mixin function goal is to bring a universal way, from ES3 to ES.future, client or server, to define functions usable as decorators for both clases and generic objects.

Following the same ES7 example used in Addy's post, based on this mixin solution.

const SuperPowers = mixin({
  init() {
    Object.defineProperty(this, '_superPowers', {value: []});
  },
  addPower(name) {
    this._superPowers.push(name);
    return this;
  },
  get powers() {
    return this._superPowers.slice(0);
  }
});

const UtilityBelt = mixin({
  init() {
    Object.defineProperty(this, '_utilityBelt', {value: []});
  },
  addToBelt(name) {
    this._utilityBelt.push(name);
    return this;
  },
  get utilities() {
    return this._utilityBelt.slice(0);
  }
});

// Usable as decorators
@SuperPowers
@UtilityBelt
class ComicBookCharacter {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
    // initialize mixins
    // if or when it's necessary
    this.init();
  }
  realName() {
    return this.firstName + ' ' + this.lastName;
  } 
};

// Usage examples
const batman = new ComicBookCharacter('Bruce', 'Wayne');
console.log(batman.realName());

batman
  .addToBelt('batarang')
  .addToBelt('cape');

console.log(batman.utilities);

batman
  .addPower('detective')
  .addPower('voice sounds like Gollum has asthma');

console.log(batman.powers);

It is also possible to use the mixin with other objects too.

// as example only, don't use at home
var SimpleEmitter = mixin({
  init: function () {
    Object.defineProperty(
      this,
      '_emitter',
      {value: Object.create(null)}
    );
  },
  on: function (type, handler) {
    (this._emitter[type] || (
      this._emitter[type] = []
    )).push(handler);
  },
  emit: function (type) {
    var args = [].slice.call(arguments, 1);
    (this._emitter[type] || []).forEach(function (fn) {
      fn.apply(this, args);
    }, this);
  }
});


var obj = SimpleEmitter({});

obj.init();
obj.on('event', function (err, res) {
  console.log(err, res);
});
obj.emit('event', null, 123);

It is also possible to define mixin constants, propeties, or static methods, passing a second object as parameter.

var WithStatic = mixin({}, {
  VALUE: 'any',
  method: function () {
    return WithStatic.VALUE;
  }
});

WithStatic.method(); // any

Which file ?

In nodejs you can either npm install universal-mixin or use universal-mixin.node.js file.

For browsers you can use universal-mixin.js file, and for AMD you can use universal-mixin.amd.js.

Compatibility

The provided functionality is compatible with IE6 or greater, Espruino, NodeJS, and other common JavaScript engines.

In pre ES5 compatible engines properties will be set enumerable and if no ES5 shim+sham is provided upfront getters and setters might not be accepted.

While IE6 and IE7 works just fine, if you are targeting IE8 please be sure ES5 shim+sham is loaded upfront. You can put this on top of your page.

<!--[if IE 8]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.1.7/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.1.7/es5-sham.min.js"></script>
<![endif]-->

Finally, you can test your browser through the test page.

universal-mixin open issues Ask a question     (View All Issues)
  • over 4 years class-like syntax
universal-mixin list of languages used
Other projects in JavaScript