Reputation: 59
I don't know how else to name the title, sorry.
Here is an example, I want to be able to do this:
var str = 'bla bla bla';
str.do(a).thenDo(b)
//but i also want to be able to do this:
str.do(a) // which will do something different
// I have tried this but it doesn't work:
String.prototype.do = function(a) {
//here is some code to get the 'str' variable, then:
var self = {};
self.thenDo = function(b) {
var someCalculations;
return someCalculations + a + b;
}
self = function() {
//this is supposed to be the do(a) function
var moreCalculations;
return moreCalculations + a;
}
return self;
}
NOTE: thenDo() needs to use the 'a' parameter from do() so something like this will not help in what i'm trying to achieve:
String.prototype.do = function(a) {
var moreCalculations;
return moreCalculations + a;
}
String.prototype.do.thenDo = function(b) {
var someCalculations;
return someCalculations + a + b;
}
//it doesnt work, thenDo() cant get the 'a' parameter
Furthermore I need this for a library that I'm developing so any jQuery answers will not help.
Thanks
Upvotes: 0
Views: 39
Reputation: 1074238
You've said:
str.do(a).thenDo(b) //but i also want to be able to do this: str.do(a) // which will do something different
It's impossible for the do(a)
part of that to do something different depending on whether its return value is used. E.g., the do(a)
part of str.do(a)
and str.do(a).thenDo(b)
cannot know it's meant to do something different in those two cases. It just doesn't have that information (which is a Good Thing™).
You could make this work:
str.do(a)(); // Does one thing
str.do(a).thenDo(b); // Does something else
Note the ()
at the end of the first one. That's the trigger that lets us differentiate the two cases:
(function() {
function String$do(v1) {
// This function is called if the caller uses () on the result
function immediate() {
console.log("something: ", v1);
}
// This is called if they use .thenDo() instead
immediate.thenDo = function(v2) {
console.log("something else: ", 1, v2);
};
return immediate;
}
Object.defineProperty(String.prototype, "do", {
value: String$do
});
})();
var str = "testing 1 2 3";
str.do(42)();
str.do(42).thenDo(67);
Side note: When extending built-in prototypes (which many advocate against), always be sure to use Object.defineProperty
or Object.defineProperties
and use the default for the enumerable
flag (or explicitly set it to false
) so you don't create an enumerable property. That won't help with naming conflicts, but it may help with code naively assuming only the default set of built-in prototype properties in for-in
loops, in
checks, etc.
Upvotes: 2