In various pieces of sample code, within the SDK samples as well as those in my book, you’ll often see the following syntax that appears somewhat cryptic (as does much of JavaScript!) to the uninitiated:
this.<some_function>.bind(this));
For example, when wiring up app bar buttons in the book’s Here My Am! examples, you’ll see this code:
var appbar = document.getElementById(“appbar”).winControl;
appbar.getCommandById(“cmdRefreshLocation”).addEventListener(“click”, this.tryRefresh.bind(this));
appbar.getCommandById(“cmdPickFile”).addEventListener(“click”, this.pickFile.bind(this));
appbar.getCommandById(“cmdRecentPictures”).addEventListener(“click”, this.recentPictures.bind(this));
The use of .bind also appears in other contexts, again from Here My Am!:
var image = document.getElementById(“photo”);
image.addEventListener(“click”, capturePhoto.bind(image));
So what’s happening here? Let’s take a step back and talk about the this keyword more generally.
this is an intrinsic variable that typically refers to the current object context on which a method is called. For example, if I have an object named obj1 and I call its obj1.doSomething method, then this inside doSomething will refer to obj1.
If I just have a global function, on the other hand, this in that context will typically be the same as window (the global context).
Event handlers present a particular difficultly with getting the this context set correctly. If you’ve defined an event handler as a member of some object, say obj1.eventHandler, and pass that function to something like addEventListener or assign it to someOtherObject.onEvent, the element/object raising that event doesn’t have your obj1 object through which to call the handler. That is, when JavaScript resolves an identifier like obj1.eventHandler, the result is just a standalone function object which has no context of where it came from.
As a result, if you do something like document.getElementById(“myButton”, obj1.eventHandler) then the function will be called, all right, but the this object within that handler will contain the global context (window) and not obj1.
The bind method solves this problem. By calling it you say, “here’s the object context through which I want this method called,” which is to say, “make this refer to a particular object when you call the method.” So if you document.getElementById(“myButton”, obj1.eventHandler.bind(obj1)) then the this object within eventHandler will, in fact, be set to obj1.
When you see the this.<event>.bind(this) syntax then, you’re just seeing an object wire one of its own methods up as an event handler and making sure that this will remain the same in the event handler.
So in the Here My Am! examples above, the event handler for the app bar buttons exist as part of the page control where this code appears. The this variable thus points to that page control object, so when the events are triggered, the handlers like tryRefresh, defined in that same page control, will have their this values set to the page control as we want.
In the second example, capturePhoto.bind(image), what we’re doing instead is making sure that the specific image element that was tapped shows up as the this object within the capturePhoto function. There are other ways to do this (getting the originating element for the event, for example), but using .bind here works nicely.