It's essential to grasp the concept of scope and closures in JavaScript.
Each time you define a function, you are essentially establishing a new level of scope. Anything defined within that function is accessible by that function as well as any other functions nested inside it. For instance:
function sayFirstName(firstName) {
//This function can access firstName
function sayFullName(fullName) {
//This function can access firstName and fullName
console.log(firstName, fullName);
}
}
Whenever the JavaScript engine encounters an RHS operand (a value on the right side of =
) that appears to be a variable name, it will search for that variable locally in the scope. If not found, it will traverse up through all enclosing scopes.
Using the previous example, if fullName
isn't found within sayFullName
, the JS engine will look through variables declared in the scope of sayFirstName
. If still not found, it will then search the global scope, which in the browser is the window
object. Failure to find the variable anywhere will result in an Error being thrown.
Now let's consider a scenario where you declare a const name
in the outer scope and proceed to create a new function, sayName
. This function has its own separate scope where everything, including function arguments, is distinct.
What happens when you execute this code:
console.log(name);
The JS engine interprets this as an RHS operation, attempting to provide the value of name
as the first argument to console.log
. It starts searching for name
beginning with the local function scope of sayName
, where it finds the variable defined in the arguments list. Therefore, it never searches beyond the function scope to locate the const name
.
You could simplify the function like so:
sayName = (foo) => {
console.log(foo);
}
The outcome would remain unchanged.