Take a look at the following function:
function sayHello(name) {
const sayAlert = function() {
alert(greeting)
}
let greeting = `Hello ${name}`
return sayAlert
}
sayHello('Alice')()
alert(greeting)
First, let's look at this interesting construction: sayHello('Alice')(). Since our sayAlert() function is the return value of sayHello, we first invoke sayHello with one pair of parentheses with our argument and then invoke its return value (the sayAlert function) with the second pair of parentheses. Notice how greeting is within the scope of sayHello, and when we invoke our function, we'll have an alert of Hello Alice. However, if we try to alert greeting by itself, we'll get an error. Only sayAlert has access to greeting. Likewise, if we tried to access name from outside the function, we'd get an error.