looping
looping

Reputation: 1161

is it a good way to return another function in javascript?

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; 
  }

Upvotes: 0

Views: 92

Answers (2)

Faiz
Faiz

Reputation: 16265

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?)

Upvotes: 2

Kevin Bowersox
Kevin Bowersox

Reputation: 94499

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.

Upvotes: 0

Related Questions