1

I have this code snipped. I'm getting a as undefined. Should this not display the parameter value passed in parent function?

function test(a) {
    return function(a) {
        console.log('a is : ' + a); // Output: a is undefined
    }();
}

test('A should not be undefined? '); 
JS-JMS-WEB
  • 2,555
  • 3
  • 17
  • 26

4 Answers4

5

Just remove the a parameter from the closure:

function test(a) {
    return function() {
       //          ^^
        console.log('a is : ' + a);
    }();
}

There are much better explanations available than this, but I'll give it a go: test is returning a function (closure) that "captures" the environment (or scope) in which it lives, including all variables, and takes them with it. Because you were passing in an argument to that function, the console.log was expecting it. But because it was an immediately-invoked function, you either needed to pass in a to the function (like Aravinder shows in his/her answer), or don't, and just allow the closure to use a that was "passed to it" from the parent function.

Hope that was helpful.

To be fair, that's not a pattern you usually come across (or, at least, I don't). You're more likely to see something like this. Here bob is a function that contains a because a was returned along with the closure when test was called.

function test(a) {
    return function() {
        console.log('a is : ' + a);
    };
}

var bob = test('A should not be undefined?');
bob();
Community
  • 1
  • 1
Andy
  • 61,948
  • 13
  • 68
  • 95
3

You should pass variable a as parameter for return self invoking function.

look this code:

function test(a) {
    return function(a) {
       console.log('a is : ' + a); 
    }(a);
}

test('A should not be undefined? '); 
Aravinder
  • 503
  • 4
  • 8
2

The issue is that the a in the console.log is the parameter to the (anonymous) inner function, which masks the one of the outer function. This can be made clearer by renaming the parameter of the inner function (α-conversion in the lambda calculus):

function test(a) {
    return function(b) {
        console.log('b is : ' + b); // Output: b is undefined
    }();
}

test('A should not be undefined? ');

As suggested by @andy, the easiest solution is to remove the parameter from the inner function. The bindings in the outer function are still visible, and so will be used instead.

Rob Hague
  • 1,409
  • 9
  • 14
1

When you describe a new function, a stands for a local variable in an inner scope which hides the a passed to a test method.

It is the same as the following:

function test(a) {
    return function(a_inner) {
        console.log('a_inner is : ' + a_inner);
    }(); // <--- here
}

After creating a function you call it without parameters (see comment "here") - this inner a is undefined. You can pass your a as a parameter in order to get the desired output:

function test(a) {
    return function(a) {
        console.log('a is : ' + a);
    }(a); // <--- and again, here. it works now
}
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101