0

when read some javascript source, I found below code:

var fullname = function(){
     var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };
        return function(name){
          return shorts[name] || name;
      }
 }();

is it more effective or other reasons by returning another function? why not use:

    function fullname(name){
         var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };
         return shorts[name] || name; 
  }
Viktor S.
  • 12,736
  • 1
  • 27
  • 52
looping
  • 1,141
  • 3
  • 11
  • 20

2 Answers2

2

This is equivalent to

var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };

function fullname(name){
      return shorts[name] || name;
}

... in what it does. But

var fullname = function(){
     var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };
        return function(name){
          return shorts[name] || name;
      }
 }();

... ensures that the hash/object shorts, is * private only to the function fullname* .

So to answer yor question, Why not

  function fullname(name){
         var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };
         return shorts[name] || name; 
  }

Here' shorts is hidden inside fullname, but as Dogbert points out, it's slower because the hash shorts is being created at each invocation.

But this gives the best of both worlds:

var fullname = function(){
     var shorts = { pos: "position", w: "width", h: "height", l: "left", t: "top" };
        return function(name){
          return shorts[name] || name;
      }
 }();

shorts remains private to fullname and at the same time, shorts is only instantiated once, so performance will be good as well.

This is what they call an IIFE (Immediately Invoked function expression). The idea is create a function A inside a function B and declare variables of use to function A within function B;s scope so that only function A can see them.

 var B = function(){
    // this is B
    // 
    val foo = {x:1}; // this is ONLY for A

    val A = function(arg0) {
       // do something with arg0, foo, and whatever
       // and maybe return something
    };

    return A;
 };

 val A = B();

As you can see, that's the same as

 var A = (function(){
    // this is in 'B'
    // 
    val foo = {x:1}; // this is ONLY for A

    return function(arg0) { // this is in A
       // do something with arg0, foo, and whatever
       // and maybe return something
    };

 })(/*calling B to get A! */);

In functionality, this is exactly the same as

 val foo = {x:1};  // foo is visible OUTSIDE foo!

 val A = function(arg0) {
    // do something with arg0, foo, and whatever
    // and maybe return something**strong text**
 };

I don't see any other use. So it's just a way of keeping variables private, and at the same time, not loosing performance.

(see What is the (function() { } )() construct in JavaScript?)

Community
  • 1
  • 1
Faiz
  • 16,025
  • 5
  • 48
  • 37
  • I'd like to add that this makes the first piece of code _much_ faster, as the variable is declared only once, than the second. Check [this benchmark](http://jsperf.com/closure-vs-no-closure-2) I created. (about 25 times faster for me in FF). – Dogbert Jan 25 '13 at 08:24
  • @Dogbert - thanks for pointing that out. And wow, somehow with a name like yours, I cannot help but readily defer to whatever you say... ;-) – Faiz Jan 25 '13 at 08:40
  • very good, I understood it very well after reading the answer. btw,the example of @Dogbert is awsome. good job!! – looping Jan 29 '13 at 07:28
0

Returning a function within another function causes a closure to be created. In this case the inner function will have access to the outer functions scope, which includes the object shorts.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189