Say we have the following sample Javascript code:
var modeller = "foo";
var provider1 = function (modeller, content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
}.bind(null, modeller);
var provider2 = function (content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
};
var createConsumer = function () {
// some arbitrary private vars
var content = 1;
var option = 2;
var doConsume = function(provider) {
provider.apply(this, [content, option])
};
return {consume: doConsume};
};
// Now use them
var consumer = createConsumer();
consumer.consume(provider1);
consumer.consume(provider2);
This is simplified a lot for demo purposes, but the gist is that provider1 is already bound, and provider2 is not - the consumer cannot pass itself as the this argument for provider1.
The questions: Is there a way to detect this kind of case where a function is already bound? Is there a way to get provider1 to use the consumer as this? Assuming the answer is no, what is the best way to work around this sort of situation?
"Is there a way to detect this kind of case where a function is already bound?"
No.
"Is there a way to get
provider1to use theconsumerasthis?"
No.
"...what is the best way to work around this sort of situation?"
Since it seems like you want to bind an argument but not the this value, I would make an argument binder method on Function.prototype that returns a function with only the arguments bound, and not this.
Function.prototype.argBind = function() {
var _slicer = [].slice,
orig_args = _slicer.call(arguments),
orig_func = this;
return function() {
return orig_func.apply(this, orig_args.concat(_slicer.call(arguments)));
};
};
Then you'd use it like this:
var modeller = "foo";
var provider1 = function (modeller, content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
}.argBind(modeller);
Now the provider1 function will be invoked with whatever normal this value is given, but the modeller will be bound as the first argument.
There is a way to detect if a function is already bound but it's not really elegant:
/\[native code]/.test(foo.toString());
Bound functions have native code as toString(). This works for Chrome(NodeJS). I don't know about other browsers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With