Guy Sela
Guy Sela

Reputation: 78

Why do immediately invoked function and non-immediately invoked function behave differently when running return statement?

I've encountered an instance of a difference between immediate invocation and non-immediate invocation of a function:

var x = (function foo() {
    return function() {
        console.log('something');
    }
})();
x();
//        logs 'something'



var x = function foo() {
    return function() {
        console.log('something');
    }
};
x();
x();
// no log at all

Why is there a difference here? In all other cases, as far as I know, immediately and non-immediately invoked functions behave exactly the same.
I didn't find any documentation on this issue.

Upvotes: 0

Views: 59

Answers (4)

Amardeep Bhowmick
Amardeep Bhowmick

Reputation: 16908

When you execute the second function expression, the expression is simply returning a reference to the inner function which is supposed to print something in the console. In other words, when x is executed it is not executing the returned function expression:

function() {
  console.log('something');
}

To do that you need to execute the returned expression by placing another pair of parenthesis ():

// x now has a reference to the outer function
var x = function foo() {
    return function() {
        console.log('something');
    }
};
//y has a reference to the inner function, as outer function has returned a ref to it
var y = x();
// To print in console, just execute the inner function
y();

In the case of IIFE, you already have the reference of the inner function when you invoke the IIFE:

//x now has a reference to the inner function
var x = (function foo() {
    return function() {
        console.log('something');
    }
})();
// you execute the inner function and print something in console
x();

Upvotes: 1

Nikos M.
Nikos M.

Reputation: 8335

var x = (function foo() {
    return function() {
        console.log('something');
    }
})();
x();
//        logs 'something'

First version immediately executes the function which returns another function which is stored at variable x. Then calling x() actually executes the internal function and somethign is logged.

var x = function foo() {
    return function() {
        console.log('something');
    }
};
x();
x();
// no log at all

Second version simply stores to variable x the external function. When calling x() it simply returns the internal function. Since that internal function is not stored or accessed anywhere, it is not called, hence nothing is logged.

What you could do (for second version):

y = x();
y(); // now logs something
// or equivalently
x()(); // now logs something

Upvotes: 2

Michael
Michael

Reputation: 5048

in case 2 you are just setting x to equal a function that returns a NON invoked function you would need to invoke that function as well with x()()

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138287

They don't behave differently in the sense that an IIFE is just a regular function call.

However in the first case, x refers to the result of the outer function being called, which is the inner function, while in the second case x refers to the outer function. Therefore in the second case you call the outer function twice, and the inner function gets returned, but you ignore that returned value. Do:

var inner = x();
inner(); // tadaa

Upvotes: 2

Related Questions