Last active
August 29, 2015 14:06
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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