Invoking a function assigned to a variable

I am currently studying JavaScript, and something’s not clear to me. Here is the code to refer to.

'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 2
console.log(i);
// returns "i is not defined"

My question is:
On line 10 ( console.log(printNumTwo()); ) the function is printed. Is it correct to assume that if I assign a function to a variable (printNumTwo, in this case) I call that same function by typing the name of the variable followed by parentheses?

And what if the function has a name and some parameters? How do I invoke it using the variable?

Thanks in advance.

It’s pretty simple.
Yes, you understand it correct that you can invoke a function which is stored in variable by just calling variable name followed by parenthesis.

printNumTwo = function() {
      return i;
    };
console.log(printNumTwo())

Now if function has parameteres than :

printNumTwo = function(x,y) {
     return x + y ;
   };
console.log(printNumTwo( 5,2 ))

And if you like to give a name to your function which is inside a variable. You can do that too.

printNumTwo = function addNumbers(x,y) {
     return x + y ;
   };
console.log(printNumTwo( 5,2 ))

Here, you assign addNumbers function to variable printNumTwo.

Now is the important thing to learn.
Even though you created named function, you can not access out side of that variable.

So, if you run this code like this :

printNumTwo = function addNumbers(x, y) {
return x + y;
};

console.log(addNumbers(5, 2));
// You will get a Nice error. 

console.log(addNumbers(5, 2));
        ^
ReferenceError: addNumbers is not defined
1 Like

then you put the arguments you want to pass in the function in the parenthesis

let addTwo = function (number) {
   return number + 2;
}

console.log(addTwo(6)); // will print 8
2 Likes

Thank you all for the quick and clear replies :wink:

1 Like

All the answers are great. I have some time on my hands this morning and thought I would add to the great answers above and explain a little further what is happening under the hood.

‘use strict’;

Using ‘let’ in this case, and not ‘var’, :+1: will scope to the environment during the execution context. What I mean by that is, for every execution (invocation, run) of any function, the JS Engine (for instance, Google’s V8 JS Engine in Chrome) will create a ‘new function execution context’ ; a stand-alone environment (“a private box”, for an anology) where the engine (the JavaScript interpretor) will work only on that function until done.

This is something I recommend looking into and learning. It makes writing and understanding code so much easier. :face_with_monocle:

let printNumTwo; // saved in the ‘heap’ : global memory.

The code statement above: we declare a variable without instantiation to use as the variable in the function expression, within the for…loop code block.

printNumTwo = function { // This is the ‘function expression’ . We assign an anonymous function to a variable: ‘printNumTwo’.

Using ‘let i = 0’ in the [ for statement ] scopes ’ i 'only to the for-loop. The variable ’ i ’ of the for-loop is ‘scoped’ (visible) to the for-loop iteration operation. The function’s “lexical” environment, (meaning it belongs to the for-loop neighborhood) can access this ‘i’ in memory.

The console.log(i) method cannot.

for (let i = 0; i < 3; i++) {

When the interpreter reads the script (the file.js) file the first time through, it only reads the code, line-by-line, and allocates (makes space at the machine level for bits and bytes) for the variable and function name’s (indentifier’s) and respective definitions, and so forth. It sets up the code to be worked on later. (And it does a lot of other things too.)

When the JS engine reads the "console.log(printNumTwo( ) ) ", the second time around, it reads the log(), then goes inside it, and reads the printNumTwo(), and because of the parentheses, it will “execute” the function, and not just return a function defintion body. SO, it goes and looks for that specific name in memory. In memory, it see’s that it was previously assigned an anonymous function ( “a function without a name”). It will then find that anonymous function’s, function definition, and together, the JS engine will now create an execution context (remember that private box I mentioned before).

Now, this is important. In this execution function context, the JS engine reads the return i ; statement within the execution context, and looks for ‘i’ inside the function body. Not there! Then it will look up to the for…loop conditional. It finds ’ i ’ there in the memory heap of the for-loop iteration. The function has access to the for-loop, and thus the variable, ‘i’.

When executing console.log(i); - the JS engine will not find that ’ i '. The function printNumTwo(){ } has closed in (closure) the ‘i’ to the function operation only. It has hidden it from the simple log() operation.

 if (i === 2) {
       printNumTwo = function() {
       return i;
};

}
}

console.log(printNumTwo()); // returns 2

console.log(i); // returns “i is not defined”

1 Like

Thank you so much! So many things to look into, but this definitely helps to uncover the shrouded mechanisms of JS.