GithubHelp home page GithubHelp logo

webreflection / universal-mixin Goto Github PK

View Code? Open in Web Editor NEW
59.0 5.0 3.0 464 KB

A mixin usable for both generic objects and decorators.

License: MIT License

Makefile 8.46% JavaScript 74.68% HTML 12.02% Shell 4.84%

universal-mixin's Introduction

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's People

Contributors

nnodot avatar webreflection avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

universal-mixin's Issues

Issue using it with backbone initialize, this is undefined

Hi,

Just wondering if you have an idea about this issue, when using it with Backbone.view it works perfectly unless I try using it with initialize, even if I use call(this), this is undefined in the initialize mixin function.

@ParentPostMessage
export default class RequestComponent extends Marionette.ItemView {

  initialize(options) {
    Backbone.Validation.bind(this, {inline: true});
    console.log(this); // Return view element
    this.initParentMessage.call(this); // also tried this.initParentMessage()
  }

--------

export default mixin({
  initParentMessage: (data) => {
    console.log(this) // return undefined
  },

class-like syntax

Is it possible to use classes to define the mixins instead of objects? I think it would look nicer...

class MyMixin {
  static a = 'a'
  b = 'b'
  init() {
  }
  static foo() { }
  bar() { }
}

invoke init on super class mixins

when class A extends B, and class B (super) has mixins decorators, calling init() in constructor of A doesn't invoke init methods of mixins from class B (super).

mixin ovveride ES6 class method

If class A has method test and mixin has function with the same name as class method definition replaced by mixin function, is that intended? I was expecting existing methods given priority over mixin functions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.