PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Eight Weeks of Prototype: Week 6, Writing JavaScript Classes with Prototype

Function Binding

When using Prototype to develop classes, you need to have an understanding of what function binding is and how to use it. Essentially what binding does is instruct what the variable this refers to in a function. This is especially useful for event handling and for handling Ajax responses.

As I showed you in the fourth article of this series ("Event Handling in Prototype"), to observe an event on an element you use theElement.observe('eventName', handler). If you are developing a class then you want your handler function to be one of your class methods. This is primarily so you can access other class methods when handling the event.

Consider the code in Listing 10. In this example, when the user clicks the button the _onButtonClick function is called. Our aim is to display the string returned by the getMessage() method when the button is clicked.

Note: My personal preference is to name event handlers using an underscore since the method shouldn't directly be called. Typically this format is used to indicate protected or private methods.

This code will not yet work, as explained following the listing!

Listing 10 Demonstrating the drawback of not using function binding (listing-10.html)
<html>
    <head>
        <title>Demonstrating the drawback of not using function binding</title>
        <script type="text/javascript" src="/js/prototype.js"></script>
    </head>
    <body>
        <div>
            <input type="button" value="Click Me!" id="myButton" />
        </div>
 
        <script type="text/javascript">
            var MyClass = Class.create({
 
                initialize : function(button)
                {
                    button = $(button);
 
                    button.observe('click', this._onButtonClick);
                },
 
                getMessage : function()
                {
                    return 'This is a simple function';
                },
 
                _onButtonClick : function(e)
                {
                    var button = Event.element(e);
 
                    var message = this.getMessage();
 
                    button.up().update(message);
                }
            });
 
            new MyClass('myButton');
        </script>
    </body>
</html>

The problem that occurs in this example is that when _onButtonClick runs, the getMessage() method is not found. This is because the keyword this doesn't refer to the instance of MyClass.

To solve this problem, Prototype provides two methods: bind() and bindAsEventListener(). They are basically the same thing, the difference being that you should use bindAsEventListener() specifically when you are observing events, because then Prototype knows to pass in the event object to the callback handler.

Listing 11 demonstrates usage of the bindAsEventListener(). This method accepts a single argument: the variable to bind the function to.

Listing 11 Binding a function with bindAsEventListener (listing-11.html)
<html>
    <head>
        <title>Binding variable with bindAsEventListener</title>
        <script type="text/javascript" src="/js/prototype.js"></script>
    </head>
    <body>
        <div>
            <input type="button" value="Click Me!" id="myButton" />
        </div>
 
        <script type="text/javascript">
            var MyClass = Class.create({
 
                initialize : function(button)
                {
                    button = $(button);
 
                    button.observe('click', this._onButtonClick.bindAsEventListener(this));
                },
 
                getMessage : function()
                {
                    return 'This is a simple function';
                },
 
                _onButtonClick : function(e)
                {
                    var button = Event.element(e);
 
                    var message = this.getMessage();
 
                    button.up().update(message);
                }
            });
 
            new MyClass('myButton');
        </script>
    </body>
</html>

Now, inside the _onButtonClick() method, this refers to the instance of MyClass, meaning the getMessage() method can now be called.

In This Article