Permalink
Fetching contributors…
Cannot retrieve contributors at this time
139 lines (99 sloc) 5.48 KB

stampit

Stampit Build Status Greenkeeper Badge npm Gitter Twitter Follow

Create objects from reusable, composable behaviors

Stamps are standardised composable factory functions. Stampit is an infected compose featuring friendly handy API.

Simplest Example

const MyStamp = stampit()       // create new empty stamp
.props({                        // add properties to your future objects
  myProp: 'default value'
})
.methods({                      // add methods to your future objects
  getMyProp() {
    return this.myProp;
  }
})
.init(function ({value}) {      // add initializers to your future objects
  this.myProp = value || this.myProp;
})
.compose(AnotherStamp);         // add other stamp behaviours to your objects

console.log(typeof MyStamp);                            // 'function'
console.log(MyStamp());                                 // { myProp: 'default value' }

console.log(typeof MyStamp().getMyProp);                // 'function'
console.log(MyStamp().getMyProp());                     // default value

console.log(MyStamp({value: 'new value'}));             // { myProp: 'new value' }
console.log(MyStamp({value: 'new value'}).getMyProp()); // new value

Stampit uses three different kinds of prototypal OO to let you inherit behavior in a way that is much more powerful and flexible than classical OO.

Status

Install

NPM

Browsers: CDNJS UNPKG

WARNING! If running in node.js <= v0.12 or IE <= 11 then you'd need to polyfill the Object.assign. Like this, or that (autodetected).

API

See the API.

What's the Point?

Prototypal OO is great, and JavaScript's capabilities give us some really powerful tools to explore it, but it could be easier to use.

Basic questions like "how do I inherit privileged methods and private data?" and "what are some good alternatives to inheritance hierarchies?" are stumpers for many JavaScript users.

Let's answer both of these questions at the same time.

// Some privileged methods with some private data.
const Availability = stampit().init(function() {
  var isOpen = false; // private

  this.open = function open() {
    isOpen = true;
    return this;
  };
  this.close = function close() {
    isOpen = false;
    return this;
  };
  this.isOpen = function isOpenMethod() {
    return isOpen;
  }
});

// Here's a stamp with public methods, and some state:
const Membership = stampit({
  methods: {
    add(member) {
      this.members[member.name] = member;
      return this;
    },
    getMember(name) {
      return this.members[name];
    }
  },
  properties: {
    members: {}
  }
});

// Let's set some defaults:
const Defaults = stampit({
  init({name, specials}) {
    this.name = name || this.name;
    this.specials = specials || this.specials;
  },
  properties: {
    name: 'The Saloon',
    specials: 'Whisky, Gin, Tequila'
  }
});

// Classical inheritance has nothing on this.
// No parent/child coupling. No deep inheritance hierarchies.
// Just good, clean code reusability.
const Bar = stampit(Defaults, Availability, Membership);

// Create an object instance
const myBar = Bar({name: 'Moe\'s'});

// Silly, but proves that everything is as it should be.
myBar.add({name: 'Homer'}).open().getMember('Homer');

For more examples see the API.

More info

Stampit was written as an example for the book, "Programming JavaScript Applications" (O'Reilly). See this page to make book examples work with the latest stampit.

Looking for a deep dive into prototypal OO, stamps, and the Two Pillars of JavaScript? Learn JavaScript with Eric Elliott.

React Users. Stampit loves React. Check out react-stamp for composable components.