Ask Dan : Procedural VS object-oriented in javascript

Since the beginning of Ask Dan a javascript question, I received a bunch of questions. Here’s the first one I received. It’s from Andrew Worcester.

There seems (to me anyway) to be an overuse of the “new” syntax in libraries. If I create an Ajax object is there a functional benefit to using: “new Ajax.Request(options)” verses something like “sendAjaxRequest(options)” It seems to me that by using “new” causes more hassle because you need to be sure the objects are properly disposed of. So is there a performance or functional benefit to this technique?

I had a hard time understanding the question (and I was too ass hole to ask…) so I’ll rephrase it in another way : is there a benefit from using object-oriented techniques VS procedural in javascript?

Procedural in javascript

Though javascript was not a procedural language from the start, it has been overused as such in the beginning (and it’s still is). That may be because people didn’t bother learning javascript and they copy/pasted functions from sites that offers low-quality javascript snippet. All they did was “hacking” the poorly written code to suit their needs. This technique worked for a long time but with the use of ajax and DHTML, it’s nearly impossible to have clean code that is not buggy and dirty.

Object-oriented in javascript

The new statement necessary implies the use of objects in javascript. You can have basic information about object in How to create objects in object-oriented javascript and in with the articles tagged Object-oriented of this site.

The benefit of object-oriented

There is one major benefit about object-oriented that creates a lot of other benefits : the cleanliness of the code. The other benefits from that are : the code is easier to maintain, to modify, to read and to explain.

OO applied

I’ll apply it to an example. I want to alert the sound of cat by ajax.

In a procedural way, you’ll approximatively have

  1. // Global variable
  2. ajaxRequest = null;
  3.  
  4. function sendCatSoundAjaxRequest() {
  5. ajaxRequest = new XMLHttpRequest(); // Create the request in the global var
  6. // … code for request …
  7. }
  8.  
  9. function receiveCatSoundAjaxRequest() {
  10. // The sound is in clear text in the response
  11. alert(ajaxRequest.responseText);
  12. }

The problems? You have a global variable to keep track of the ajax request. Because it could be use by every other functions that need ajax, you can’t make more than one request at a time. Also, there are nothing that binds the two methods together apart their names that are look alike. Now, just think of the code when you have 5 or 6 different type of requests. Your code will look like garbage.

In a object-oriented way, you would all write this ugly code in a separated object. Your main call to see the sound of a cat could be something like

  1. var cat = new Cat();
  2. alert(cat.getSound());

The code from above still exists somewhere but the complexity is now hidden behind the Cat class.

Commentaires

  1. BK June 7 2007 at 07:27:42

    Other benefits could be the parameters and state store and also the possibility to move the object around.

    The sample syntax you submitted in your question isn’t quite descriptive and may prohibit to really understand the benfits. Say we rewrtie this as
    new Ajax.Request(ServerName, PortName)
    From there, you can then easily build new functions which receives your new object to easily communicate with the server. For instance, you could then have a script which would look like

    var conn = new Ajax.Request(ServerName, PortName)
    var cat = new Cat(conn)
    cat.getSound()
    cat.getFood()
    var dog = new Doc(conn)
    dog.getSound()
    dog.getFood()

    instead of
    getCatSound(ServerName, PortName)
    getDogSound(ServerName, PortName)
    getCatFood(ServerName, PortName)
    getDogFood(ServerName, PortName)

    The second example could be a definite hassle to maintain. Also, the first example could easily manage things like connection pooling, performance stats, connection hacks, … In the second method, it would be quite difficult since there is no centralized interface.

    About the disposal of objects, except for COMs, do you have any documentation showing it is necessary to dispose of JS objects? Because since “everything is object” in JS (any function declaration creates a Function object), I don’t think so or else, for every function we declare, we would have to dispose of them giving something like:

    function test(){alert(”test!”)}

    and don’t use a declared function because you would then create another undisposed object… I don’t think it could work like that…

  2. Dan (maintainer of Javascript Kata) June 8 2007 at 18:50:57

    Thanks BK for your comment… that’s a great example.

  3. -RE June 22 2007 at 09:22:50

    It’s like, what use are these fancy, high-level named variables when you can stuff your values into registers ? ;-)

  4. DB July 11 2008 at 09:01:06

    One can use a procedural approach to invoke AJAX functionality without the use of global variables so I don’t understand how use of globals is a telling point against the procedural approach. (See the example below).

    After writing my library functions I can call them from any point in my code, and reuse them without any conflicts that might arise from the use of globals:

    InvokeAJAXRequest(”dog”,”sound”);
    InvokeAJAXRequest(”cat”,”food”);

    The code funnels through the InvokeAJAXRequest function which avoids the objection of no centralized interface.

    Both the “must use globals” and “no centralized place to make changes” are straw man objections. Bad code is bad code regardless of approach.

    Moreover, I can accomplish the same tasks using considerably less keystrokes then the approach espoused elsewhere on this page.

    function InvokeAJAXRequest(animal,responseType)
    {
    var url = animal + responseType + “.html ”
    var xmlhttp = getHTTPRequest();

    xmlhttp.open(’GET’, url, true);
    xmlhttp.onreadystatechange = function() {
    if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
    {
    DoWhateverWithTheResponse(xmlhttp.responseText);
    }
    else
    {
    window.status = “Loading…”;
    }
    };
    xmlhttp.send(null);

    }
    function getHTTPRequest()
    {
    // native XMLHttpRequest (Firefox et al)
    if (window.XMLHttpRequest)
    {
    req = new XMLHttpRequest();
    return req;
    }
    //IE 6
    else if (window.ActiveXObject)
    {
    req = new ActiveXObject(”Microsoft.XMLHTTP”);
    if (req)
    {
    return req;
    }
    }
    }

    function DoWhateverWithTheResponse(text)
    {
    // Plug your returned HTML into the page
    }

Post a comment

Comments are moderated and innapropriate ones won't be approved. Please respect this public space.