composer.js
v0.2.3
Published
Dead simple prototypical OO with musical flavor
Downloads
4
Readme
Composer.js
Ever needed a simple library to express ALL of your object creation? You have probably used (or just tried) libraries that try to sugarify the process to make it feel more classical. Well, just so you know, that method is dead.
In this page, I will show you how to write objects better using Stampit()
or Composer()
. I will even outline the differences so you can make an informed decision on your project and write better code!
So here's what you do instead:
Ditch your compositional library!
Include one of these scripts on your page or node.js
application:
Stampit
npm install stampit --save
- Stampit Github Repo
- Stampit NPM Repo
- Minified Javascript
Composer
npm install composer.js --save
- Composer Github Repo
- Composer NPM Repo
- Minified Javascript
Create a factory!
- Stampit:
var factory = Stampit();
- Composer:
var pieceFactory = Composer();
Now instead of defining your object as a constructor, let's make some closures.
function closure(){
var store = {};
_.mixIn(this, {
"get": function(val){
return store[val];
},
"set": function(val, value){
store[val] = value;
return this;
}
});
}
This closure is very simple, and defines a private variable store
behind the scenes. Then it mixes into this
functions called get
and set
.
There are 3 ways to use this (given an object myObject
for factory-less):
var myObject = {};
closure.call(myObject);
var getsetFactory = Stampit().enclose(closure);
var getsetFactory = Composer().phrase(closure);
... and finally if you used a factory...
myObject = getsetFactory();
Give your object some Default Values!
States allow you to set properties inside of the object at creation time.
Noting the difference between the phrase
(composer) function and the state
(stampit) function, the phrase
function is both the enclose
function and the state
function in stampit.
Using stampit:
Stampit().state({
some: "properties",
go: "here"
});
Using composer:
Composer.phrase({
some: "properties",
go: "here"
});
Obligatory mixin without factories example:
_.mixIn(obj, {
some: "properties",
go: "here"
});
Create a Prototype!
Some good ways to do prototype creation:
var myPrototype = {
"test": function(){
return "test";
},
"test2": function(a){
return a;
}
};
//Copy that prototype
var myobj = Object.create(prototypeDefinition);
//stampit example
var factory = Stampit().methods(myPrototype);
//Another stampit method
var factory = Stampit(myPrototype);
myobj = factory();
//Composer
var piece = Composer().motif(myPrototype);
myobj = piece();
myobj.test();
//"test"
myobj.test2(2);
//2
All of these functions are designed to place items on the object's prototype. Don't put static values here. Put them on the factory or in a namespace for later use so that they can be encapsulated instead of injected into the global namespace.
Composer also supports the following syntax:
piece.motif(function functionName(){
//Your prototype definition goes here
return "functionValue";
});
var myObj = piece();
myObj.functionName();
//"functionValue"
The name functionName
will be added to the piece prototype.
Define a few properties!
This is rather tricky, because IE8 does not support getter and setter properties of any kind. Yet, Composer and Stampit can help you do this.
Upon object creation you can create a closure like this:
//Stampit
factory.enclose(function(){
Object.defineProperty(this,"propertyName",{
"get": function(){},
"set": function(){}
})
});
//Composer
piece.phrase(function(){
Object.defineProperty(this,"propertyName",{
"get": function(){},
"set": function(){}
})
});
or you can use Composer's dynamic function:
piece.dynamic({
"propertyName":{
"get": function(){},
"set": function(){}
}
});
Under the hood composer uses Object.defineProperties. This is not recommended for people who have to support older browsers, because there are no polyfills for this method.
Combine some factories! (and a few other things too)
Stampit Example
var newFactory = Stampit.compose(factory1, factory2, factory3...);
Composer Example:
var newPiece = Composer.symphony(piece1, piece2, closureOrPhrase, stateOrPhrase);
Note that closures, states, and pieces will be added in the order they are placed in the function for composer.
Parameters for Functions and Chainability
Every function described here accepts unlimited parameters so long as it matches the definition of the API.
//stampit example
var factory = Stampit().enclose(functionDefinition1, functionDefinition2,...);
//composer example
var piece = Composer().phrase(functionDefinition1, functionDefinition2, state1, state2...);
The API of both libraries is chainable.
var factory = Stampit().enclose(...).methods(...)...;
var piece = Composer().dynamics(...).phrase(...).motif(...)...;
Compose and Symphony return a factory so they should be chainable as well.
var piece = Composer.symphony(piece1, piece2).dynamics(...).phrase(...).motif(...)...;
Make your Library!
Composer was designed with portability in mind. Check out the following example.
var store = Composer().phrase(function(values){
var key, myStore = {};
for(key in values){
set(key, values[key]);
}
function get(myKey){
return myStore[myKey];
}
function set(myKey, val){
myStore[myKey] = val;
return this;
}
this.set = set;
this.get = get;
});
Now just use your factory.
var myStore = store({
"foo": "bar",
"baz": "nee"
});
myStore.get("foo");
//"bar"
myStore.get("baz");
//"nee"
myStore.set("baz","blah").get("baz");
//"blah"
All parameters passed to the factory constructor get passed to the closures. Your library is now extendable using this API. Allow your users to mix/match/create a new library based on your own.
At this time, stampit does not support passing variables to the closures and sometimes it really isn't useful. In that case, use stampit.
Test Composer!
If you don't have Mocha installed, it's probably best to run npm start
from a cloned repository. This process will install mocha globally and allow you to run mocha tests from the command line.
No mocha (Only need to run once):
npm start
Then just run:
npm test
Be Free!
Whatever library you choose to define your objects, always help out and file bug reports if found.
Please feel free to file an issue or submit a pull request with a small summary of suggested changes!
I'm looking for help wherever I can get it to help maintain this library. Feel free to email me at [email protected].
Thank you very much for your time and good luck with your javascript applications~
~function(){console.log("Josh");}();`
//"Josh"