Produces a function that remembers the first parameter (‘man’) because the function greeting only has one parameter; it will ignore the other two.
The produced function, now called ‘myMan’ now receives 2 parameters because that’s how it’s defined. If you call it with 0 arguments myMan(), the defined parameters will be forced to be filled with undefined hence the result undefined my man, how are you? How's the undefined?
No matter how many times you call it, it will produce the same output since there’s no side-effects (other than the console.log ofc) or variable mutation. Doesn’t matter if you call it once with the two expected parameters, if you call it again with 0, it will produce what you expect: undefineds. The only paramter being closed over is greet which is specified in the outer function greeting the others are still expecting a value.
Responding to a comment:
//Also this function executes itself when declared inside a constant. Why?
That’s because if you assign a function call to a variable/constant, it needs to be executed/called in order to fetch the returning value from the call. There is a console.log statement so it gets executed and there’s no return statement so the interpreter will return undefined for you.
//I declare my function
function greeting(greet){
return function(name, who){
console.log(`${name} my ${greet}, how are you? How's the ${who}?`);
}
}
//I declare my variable where I store the function's result
const myMan = greeting("man");
//This is an instance of greeting() so that's the only parameter it will recognize
//And if I call this instance of greeting()
myMan("Bob", "wife")
//Output:
//"Bob my man, how are you? How's the wife?
So I can only think that when I call this new function, I somehow “moved down” inside the greeting() functions’ body, specifically to this line:
**return function(name, who){}**
since the parameters I passed to this function stored in a variable are now recognized as the inner function’s name and who parameters.
Well, I’ll keep studying so I can refine my understanding of this and get a good grasp of what’s happening here.
That’s basically it but you should not refer to “something being an instance” when there’s no prototype, this or objects involved. A closure is nothing but stack frames being linked when there’s a reference to an outer variable from an inner stack frame or returned function that’s executed later on. Trying to understand closures at a lower level requires knowledge of stack frames, heap memory allocation and references.
It’s best to just think about it as – a reference to a variable being kept when the innermost function of a function-return-chain is assigned to a variable in order to be called later on potentially multiple times.
So your myMan absolutely (I mean really absolutely) have no idea what’s greeting is. Fast forward to the point when you invoke myMan - you have references to 3 variables and what JS engine will do, it will start looking for them: it will find name and who right away in the scope of myMan and it will find greet in the next higher scope of greeting function, that was preserved because myMan function was declared in that scope. This behavior of scope preservation is called closure - JS engine is enclosing scope of greetings and myMan function together.