Function binding in Javascript

Javascript functions are extremely flexible. Functions that are defined on one object can be called from different objects either directly or indirectly using apply() or call() methods.

So, the use of the ‘this’ keyword during runtime may not be a reference to the intended object. Fixing the value of the ‘this’ reference is referred to as function binding.

By default, a function defined outside any explicit object is bound to the current window object (‘window’). Functions defined inside a specific object have a default binding to the container object.

When you pass a method as an argument to be invoked later. if the invocation does not use its object, the binding is lost! Passing functions as arguments happens a LOT in prototype- esp when using Ajax libraries.

Here is an example of a potential bug that can creep in due to improper function binding:

var myObj={
name:’My object’,
getName:function(){
return this.name;
}
};

window.name=’This is the window object’;

debug.write(myObj.getName());
    //this prints out "my object".as expected

function callFunction(fx){
return fx();
}
callFunction(myObj.getName);
    //this prints out "This is a window object"!!

The first function invocation i.e. myObj.getName() works as expected as the default binding comes into play. Even though there is a window.name defined, the binding occurs within the scope of the object myObj.

The second function invocation is where things get interesting.

callFunction(fx) is a global function that takes a function as an argument and executes it. The ‘this.name’ variable in the getName function now gets bound to the window and displays the value of window.name instead of myObj.name.

The Prototype library provides two methods to remedy this.

  • bind(thisRef)
  • bindAsEventListener(thisRef)

An updated version of the code we just wrote using the bind() function is:

var myObj={
name:’My object’,
getName:function(){
return this.name;
}
};

window.name=’This is the window object’;

debug.write(myObj.getName());
    //this prints out "my object".as expected

function callFunction(fx){
return fx();
}
callFunction(myObj.getName.bind(myObj));
//’My object’.. works as expected!

The bindAsEventListener() method is to be used to properly bind functions when registering events in prototype. The bindAsEventListener() works just like bind() but also preserves the current event as the first argument. So, in your function you can perform tasks with the event such as stopping further event bubbling – Event.stop(e)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s