0

This question is directly applicable to only a somewhat specific use, and both forms work fine in my application, but I suspect that any difference (or indeed, a lack of differences) between the two forms would be enlightening as to how exactly the prototype chain and method binding work in Javascript/ECMAScript.


What is the difference between:

obj[method].bind(obj)

And:

Object.getPrototypeOf(obj)[method].bind(obj)?

And why are they different or why are the same?


Obviously, obj.method is different from Object.getPrototypeOf(obj).method in that the first is bound with this = obj, whereas the second is not.

However, if you take obj.method out of its original context in the code, such as by putting it in an array or passing it into a callback, then it seems to me that it also sometimes becomes unbound.

Both obj.method.bind(obj) and Object.getPrototypeOf(obj).method.bind(obj) seem to differ from both those behaviours in that their values can be put in containers, passed into callbacks, or stored as variables, and remain bound.

I think I've noticed var self = obj; self.method exhibiting the same kind of "stronger" binding too.

It seems a little bit non-obvious too that obj.method, which is already bound, can be bound again with obj.method.bind() and end up behaving differently from how it was before but seemingly identically to Object.getPrototypeOf(obj).method.bind().


So it seems to me that there are at least three and possibly four different levels of method "binding":

  1. Object.getPrototypeOf(obj).method or funct.prototype.method (or just function(){}):
    • Completely unbound.
  1. obj.method:
    • Bound, but only within its original scope and not if passed into a callback or shared via a container, as if the interpreter situationally propagates the value for this from the calling original calling scope rather than creating a new function/method that's actually bound.
  1. obj.method.bind(obj), Object.getPrototypeOf(obj).method.bind(obj), or (function(){}).bind(obj):
    • Bound, and still bound when called from outside its original scope, meaning that this must be stored within the function/method itself.
    • Behaves identically to each other, even though the first form starts from what's already supposed to be a bound method and the latter two start with unbound functions?
  1. var self = obj; self.method
    • Also bound, and still bound when called from outside its original scope, meaning that this must be stored within the function itself?

There might be additional differences when using this instead of obj, or some of these differences might only show up when using this instead of obj, too.

Will Chen
  • 217
  • 2
  • 9
  • 1
    The prototype chain has nothing to do with function binding. Your two syntaxes differ only in that the latter ignores own properties and always directly accesses the method with that name on the prototype. – Bergi Jul 01 '20 at 07:43
  • 1
    "*`obj.method`, which is already bound*" - no, it's not. Methods in JavaScript are getting bound dynamically when called, not when being accessed. "*as if the interpreter situationally propagates the value for `this`*" is exactly [what happens](https://stackoverflow.com/q/3127429/1048572). – Bergi Jul 01 '20 at 07:44

0 Answers0