Create objects from reusable, composable behaviors
Stamps are standardised composable factory functions. Stampit is an infected compose featuring friendly handy API.
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.
- v1.
npm i stampit@1
- v2.
npm i stampit@2
Breaking changes - v3.
npm i stampit
Breaking changes. Compatible with the stamp specification
Via bower:
$ bower install stampit
or
$ bower install stampit=https://npmcdn.com/stampit@3/dist/stampit.umd.min.js
or
$ bower install stampit=https://unpkg.com/stampit@3.1.2/dist/stampit.umd.js
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).
See the API.
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.
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.