2

[This is related to Bound function instead of closure to inject extra arguments, but that was neither clearly asked nor answered.]

I'm calling a function that expects a function as its argument. I want to pass a method from my class, bound to an instance of my class. To make it clear, assume my class looks like:

var MyClass = function() {}
MyClass.prototype.myMethod = function() { ... }

var my_instance = new MyClass();

Is there any substantive difference between using bind:

doSomething(my_instance.myMethod.bind(my_instance))

and wrapping the call in an anonymous function:

doSomething(function() { my_instance.myMethod(); })

?

Community
  • 1
  • 1
fearless_fool
  • 33,645
  • 23
  • 135
  • 217
  • The effective difference is *when* `my_instance` (and `my_instance.myMethod`) is resolved. Assuming that none of the bindings change they will both have `this` of "my_instance" when the method is invoked. There will be slight differences with the call frames, but *shrug*. – user2864740 Mar 24 '16 at 21:44
  • I'm not really sure what 'better' means here, since `bind` is considered. – user2864740 Mar 24 '16 at 21:49
  • @user2864740 I removed the "is there something better" question since it muddies the primary intent of this post. – fearless_fool Mar 24 '16 at 21:55
  • @user2864740 Post your first comment as a response and I'll give it a checkmark. I hadn't considered the time at which the args are bound. – fearless_fool Mar 24 '16 at 21:56

1 Answers1

1

If a prototype within your class needs to generate a callback, it may not know its instance's name. As a result, you'll need to use this, but the value of this depends on where the callback was executed.

Consider the following example:

var MyClass = function (x) { this.something = x; };
MyClass.prototype.makeCall = function () {
    var myBadCallback  = function() { console.log(this.something); };
    var myGoodCallback = function() { console.log(this.something); }.bind(this);

    // When called, the value of "this" points to... we don't know
    callMeBack( myBadCallback );

    // When called, the value of "this" points to this instance
    callMeBack( myGoodCallback );
};


function callMeBack( callback ) { callback(); };

var foo = new MyClass('Hello World!');
var bar = new MyClass('Goodbye!');

// Probably prints "undefined", then prints "Hello World!"
foo.makeCall();

// Probably prints "undefined", then prints "Goodbye!"
bar.makeCall();

In the above example, the first output probably prints undefined because the context (what this refers to) has changed by the time the callback has executed.

This example may seem contrived, but these sort of situations do arise, a common case being AJAX callbacks.

Mr. Llama
  • 20,202
  • 2
  • 62
  • 115