views:

134

answers:

2

I've been getting into OOP javascript recently and more and more I've been hearing about closures. After a day of twisting my brain I now understand them* but I still don't see the advantage over using an object. They appear to to do the same thing but I suspect I'm missing something.

*i think

Edit

I've just spent 20 minutes trying to write an example using a counter written as an object and a counter written as a closure. I have come to the conclusion that I still don't understand closures.

2nd Edit

Ok I've managed to whip of an extremely simple example. There isn't much between these two but I find the object version more readable. Why would I chose one over the other?


/*** Closure way ***/

function closureCounter() {
    var count = 0;
    return {
        increase : function() {
            count++;
            alert(count);
        },
        decrease : function () {
            count--;
            alert(count);
        }
    };
}

var myCounter = closureCounter();

myCounter.increase();
myCounter.decrease();


/*** Object way ***/

function objCounter() {
    var count = 0;
    this.increase = function() {
        count++;
        alert(count);
    }
    this.decrease = function() {
        count--;
        alert(count);
    }

}

var myCounter = new objCounter();

myCounter.increase();
myCounter.decrease();





+3  A: 

You don't have to risk additional bugs and confusion by creating a whole new object when a closure will do the same thing with cleaner and simpler code. With closures, it's much easier to link objects.

Case in point:

function attachOnclick(eSource, eParent) {
    var e = document.createElement("div");
    eParent.appendChild(e);
    eSource.onclick = function() { e.style.backgroundColor = "881010"; }
}

versus

var elemLinks = [];
function attachOnclick2(eSource, eParent) {
    var e = document.createElement("div");
    eParent.appendChild(e);
    elemLinks.push({elemSrc: eSource, elemDest: e}); // Append to mappings list
    eSource.onclick = changeColor;
}

function changeColor() {
    for(var i = elemLinks.length; i--;) {
        if(this == elemLinks[i].elemSrc) { // We've found our match
            elemLinks[i].elemDest.style.backgroundColor = "881010";
            return true;
        }
    }

    return false;
}

If you find any bugs in the second sample, then it just proves my point that closures make writing simple, cleaner code easier.

palswim
+1 for disclaimer at the end =P
Josh Smeaton
+2  A: 

Like masterik said, you're comparing apples and oranges.

An object is just a collection of key/value pairs. A closure relates to variable scoping. You can create a closure in any scenario, by wrapping that part of your code in a function. This creates a new closure within that function scope.

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

The difference between your two examples of object creation is related to different patterns of writing classes/objects in JS. The first example I believe is called the Module pattern? The second example is another common way of defining classes in JS, or you could also use the object's prototype to add those methods.

For more information on how to write classes, try googling "js class patterns" (there are quite a few resources, with different patterns - module, revealing module, singleton, etc)

alex
Thanks, this is making more sense now. That article you've linked to really helped.
MrMisterMan