Skip to content

Instantly share code, notes, and snippets.

@Winchestro
Last active August 29, 2015 14:06
Show Gist options
  • Save Winchestro/5076d2eda6acc51d41be to your computer and use it in GitHub Desktop.
Save Winchestro/5076d2eda6acc51d41be to your computer and use it in GitHub Desktop.
Chaining method calls with getters. Instead chaining someObject.chain.s().o().s(); it allows to write someObject.chain.s.o.s;
/*
This is a little experiment using getters to chain method calls.
First we have the example object
*/
var someObject = {
someMethod:function(){console.log("someMethod called with",arguments);
return this;
},
someValue:0,
otherMethod:function(n){
this.someValue+=n;
console.log("otherMethod incremented property ", this.someValue," by ",n);
return this;
}
};
/*
Here is the first and longest version of the snippet.
-pass any object and a description of the methods and the alias you want to call it by.
-arguments are supported but *super confusing*. They apply to the _next and all successive_ chain calls. That's why I added a log. It's madness.
-in order to start chaining you have to enter the chain-property on the object, here I called it "chain", you'd probably rename it to "$"
*/
(function(target,alias){
var args;
var log=[];
var temp;
function traveler(){
args=Array.prototype.slice.call(arguments);
return target.chain;
};
traveler.toString=function(){
temp=log.slice(0);
log.length=0;
args=null;
return temp.join("\n");
};
Object.keys(alias).forEach(function(method,index){
Object.defineProperty(traveler,method,{
get:function(){
log.push(
[method,"(",args,")"].join("")
);
return target[alias[method]].apply(target,args).chain;
}
});
});
Object.defineProperty(target,"chain",{
get:function(){return traveler;}
});
})(someObject,{s:"someMethod",o:"otherMethod"})
/*
Here is a much smaller version of it without the log
*/
(function(target,alias){
var args;
function traveler(){
args=Array.prototype.slice.call(arguments);
return target.chain;
};
Object.keys(alias).forEach(function(method,index){
Object.defineProperty(traveler,method,{
get:function(){
return target[alias[method]].apply(target,args).chain;
}
});
});
Object.defineProperty(target,"chain",{
get:function(){return traveler;}
});
})(someObject,{s:"someMethod",o:"otherMethod"})
/*
Here is one without arguments (will cause the example object to go all NaN on the otherMethod but it works)
*/
(function(target,alias){
function traveler(){};
Object.keys(alias).forEach(function(method,index){
Object.defineProperty(traveler,method,{
get:function(){
return target[alias[method]]().chain;
}
});
});
Object.defineProperty(target,"chain",{
get:function(){return traveler;}
});
})(someObject,{s:"someMethod",o:"otherMethod"})
/*
Here is the last version in uglified if you are into such things.
*/
(function($,a){(function(o,d){function t(){};o.keys(a).forEach(function(m){o[d](t,m,{get:function(){return $[a[m]]().µ;}});});o[d]($,"µ",{get:function(){return t;}});})(Object,"defineProperty")})
(someObject,{s:"someMethod",o:"otherMethod"})
/*
And the version without log but with arguments uglified
*/
(function($,_){(function(o,d){var a;function x(){a=Array.prototype.slice.call(arguments);return $.µ;};o.keys(_).forEach(function(m){o[d](x,m,{get:function(){return $[_[m]].apply($,a).µ;}});});o[d]($,"µ",{get:function(){return x;}});})(Object,"defineProperty")})
(someObject,{s:"someMethod",o:"otherMethod"})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment