views:

80

answers:

2

Hi, I'm trying to simplify some JS code that uses closures but I am getting nowhere (probably because I'm not grokking closures)

I have some code that looks like this:

var server = http.createServer(function (request, response) {
var httpmethods = {

       "GET": function() { 
                      alert('GET')
                     },
       "PUT": function() {
                      alert('PUT')
                     }
       };
});

And I'm trying to simplify it in this way:

var server = http.createServer(function (request, response) {
var httpmethods = {

        "GET": function() { 
                      alertGET()
                     },
        "PUT": function() {
                      alertPUT()
                     }
       };
});

function alertGET() {
        alert('GET');
}

function alertPUT() {
        alert('PUT');
} 

Unfortunately that doesnt seem to work... Thus: - what am I doing wrong? - is it possible to do this? - how?

TIA

-- MV

A: 

Not setting up the object properly, you're putting the function names as strings inside the httpmethods object, instead of giving them names - try something like this:

var server = http.createServer( function (request, response) {});

var httpmethods = {
    get: function() { 
      alertGET()
    },
    put: function() {
      alertPUT()
    }
};

function alertGET() {
        alert('GET called');
}

function alertPUT() {
        alert('PUT called');
}

httpmethods.get()
httpmethods.put()

This is the way you define the methods inside the object, but not sure about the other stuff you have there (http.createServer()...?)

danp
I've no idea what's inside the http.createServer() method.. without seeing the whole code, it's a little tricky, but the basic problem is the way you are defining the .get() and .put() functions on the httpmethods object. take the quotes off them, and it should be fine.
danp
the quotes is of no issue - they are perfectly legal.
Sean Kinsey
This example perfectly examplifies properties of object literals but does nothing to demonstrate closure.
+1  A: 

In JavaScript a closure is a variable declared in one function that is used in child functions. JavaScript is a lamda language, which basically means that scope to defined by some type of object, in this case a function, and child objects of that type inherit scope from the parent.

Here is a simplified example:

var parentFunction = function (x) {  
    var a = 5,
    childFunction = function () {
        a = a + x;
    };
    if (x < 5) {
        childFunction();
        return a;
    } else {
        return a;
    }
};

In that example variable a is a closure to function childFunction. The child function receives access to the variable declared in the parent function and can supply a new assignment to that variable. Since a is declared in the parent function is avialable to all descendents of that parent function.

Notice also how I declared my functions different than you do in your example. This is actually important to proper programming if you actually do make use of closure. Function names are always variables and like any other variables are subject to closure. This means if you are not absolutely certain of your namespaces and scope definitions you can very likely encounter collisions. Your named functions have an applied name property that moves the variable name to the top of the stack in the given namespace. This allows you to execute a function before its name is declared.

When a function is declared like in my example the variable is not provided a name property, so the function must be declared before it is executed. This is important to proper programming, because it forces strict awareness of namespace. That is good because it prevents you from making collisions if you ever create another variable with the same name in a different scope. Reusing variable names may not sound common, except if you ever write code containing dozens of functions and thousands of variables. It is common to use a single character variable name for the incrementer of a for loop, but keep in mind there are only 26 letters available and you may write code large enough to contain over a hundred such loops.

To see a more complicated example of closure and variable reuse take a look into my tab_level function in the following JavaScript. When looking at that example keep in my its logical complexity upon variable names and given scopes even though it is only a mere 800 lines of code.
http://mailmarkup.org/prettydiff/markup_beauty.js