Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript closures -- what is the difference between these

EDIT

With the number of responses saying "you can make private things!" below, I'm going to add this to the top as well:

I know you can emulate private variables within a closure. That is not what I'm asking. I'm asking, given the two examples below where I'm "exporting" EVERYTHING from the closure, what is the fundamental difference between these two examples.

Given these two methods of creating objects/methods:

var test = {}

test = (function(){
    var a_method = function(print_me){
        return "hello "+print_me;
    }

    return {print_me: a_method};
})();

test.print_me2 = function(print_me2){
   return "hello "+print_me2;
}

test.print_me('world');
>>> returns "hello world"

test.print_me2('world');
>>> returns "hello world"

I understand that the first method allows for private variables (which as a python developer at heart i don't really care to use), but both seem rather equivilent to me, only the first one looks "cooler" (as in all the big javascript people seem to be doing it that way) and the second way looks very passé.

So, like, what is the difference?

I've looked through the closure questions here -- most of them center around what or why do you use them; I understand their utility, I just want to know why you'd do the first over the second and what benefits it has.

I'd prefer hard evidence over conjecture -- not looking for a "this is how the cool kids are doing it" or "i heard that mozilla does better memory usage when you use a closure", but rather qualitative evidence towards one being 'better' than the other.

like image 305
tkone Avatar asked Feb 09 '12 12:02

tkone


2 Answers

The difference between the methods is the anonymous function wrapper that creates a closure, but also that the first method replaces the entire object while the second method just sets a property in the existing method.

There are different ways of adding methods to an object. You can put them there when you create the object:

var test = {
  print_me: function(text) { return "hello " + text; }
};

You can add a method as a property to an existing object:

var test = {};
test.print_me = function(text) { return "hello " + text; };

You can make a constructor function, and add methods to its prototype:

function Test() {}
Test.prototype.print_me = function(text) { return "hello " + text; };
var test = new Test();

As Javascript has a prototype based object model, the last one is how methods were intended to be created. The other ways are just possible because an object property can have a function as value.


You can use a function wrapper around any code where you want local variables, so you can do that with the second way of setting the property:

test.print_me2 = (function(){

  var method = function(print_me2) {
    return "hello "+print_me2;
  }

  return method;
})();
like image 145
Guffa Avatar answered Sep 23 '22 21:09

Guffa


In the first example, the closure is used to keep local variables out of the global scope.

var thisIsGlobal = 2;
var test = (function () {
  var thisIsLocal = 3;
  return function () {
    return thisIsLocal;
  };
}());

What you get is a function test which when invoked returns the value of the local variable thisIsLocal. There is no way to change the value of the variable. You can be look at it as to a private variable.

like image 43
J. K. Avatar answered Sep 21 '22 21:09

J. K.