I\'m getting my head wrapped about currying and other techniques using Function.prototype.bind.
It seems extremely useful to change function scope (i.e., this
What the bind
method basically does is something like (not exactly, because arguments are sliced to exclude the context):
function bind(context) {
var self = this;
return function() {
self.apply(context, arguments);
}
}
So basically it's returning another function which will call itself with the given context and arguments. If you then bind
it again, you'll be binding this newly created function, which will be as if bind
was implemented like:
function bind(context) {
var self = this;
return function() {
self.apply(context, arguments);
}.bind(otherContext);
}
But because the inner function returned by bind acts as a closure where the original context is the one binded first (self
), that one will be the context in with your function will be really executed.
This would actually solve you issue
const bind = Function.prototype.bind;
Object.defineProperty(Function.prototype, 'bind', {
value: function () {
const result = bind.apply(this, arguments);
result.source = (this.source || this);
return result;
}
});
Now you can get the source
property to get the original function.
This could cause other issues, but performance does not seem to be one of them, https://jsperf.com/bind-override/1
Both IE, Edge, Firefox and Chrome seems to get the same result, sometimes the normal version is faster and sometimes the overridden is faster.
I thought it would be useful to illustrate Win32's answer with a picture.
A wrapper generated by bind
makes sure your function is called with given context no matter what.
Such wrapper will always ignore its own context.
Given a chain of wrappers, any context but the innermost is lost.
Therefore, there is no way to change the context once it has been set using bind
.