18

Is there a way to rebind a function that is already bound to another object via Function.prototype.bind?

var a={};
var b={};
var c=function(){ alert(this===a); };
c(); // alerts false
c=c.bind(a);
c(); // alerts true
c=c.bind(b);
c(); // still alerts true

I know that I can use a different approach and keep a "clean" function for binding, but I just wonder how to reuse an already bound function.

1
  • 1
    comparing objects with === is a bad idea... Commented Jul 27, 2015 at 15:03

2 Answers 2

16

Is there a way to rebind a function that is already bound to another object via Function.prototype.bind?

No. From the ES2015 spec about Function.prototype.bind:

19.2.3.2 Function.prototype.bind ( thisArg , ...args)

[...]

Note 2: If Target is an arrow function or a bound function then the thisArg passed to this method will not be used by subsequent calls to F.

This was already true for earlier versions as well.

Sign up to request clarification or add additional context in comments.

5 Comments

Is there any reason you can think of why is that? It's pretty weird that JavaScript tries so hard to be flexible (yet all this bind hassle), but doesn't even allow to rebind the value.
.bind seems to provide a very strong contract, i.e. it guarantees that no matter how the function is called, this will point to the value I defined. If it was possible to again change the value of this somehow, .bind appears to be less useful.
Yeah, it looks like a VERY strong contract. I would like to be able to set my own default binding and allow clients of my code to rebind it though.
You can do this manually by enabling clients to supply the receiver via an argument, and having a default receiver in the event one is not supplied. Just because the language is flexible in one dimension, does not necessarily mean it is flexible in another (indeed why would it?!). In this instance, given that control of the receiver can be delivered in userland, a non-userland guarantee of the receiver is a useful addition to the language.
I also wouldn't be surprised if engines implemented bind by just creating another function which wraps a call under the hood and that doesn't suggest an elegant way to rebind. Besides, Ben's point that if you want this functionality you can implement it yourself is a good one.
12

What .bind() does is almost the same as this:

function likeBind(fun, thisValue) {
  return function() {
    var args = [].slice.call(arguments, 0);
    return fun.apply(thisValue, args);
  };
}

So:

c = likeBind(c, a);

gives you a bound function. Now, even if you attempt to re-bind, the original bound function still exists in that closure with the value you originally requested to be used as this. Values of variables inside closures can only be changed from inside the closure, so there's nothing you can do to un-bind a bound function like that. You have to start over from the original function.

So, no.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.