JavaScript Introduction | Functions | Function Scope

Function Scope

In most programming languages, variables defined inside a block cannot be accessed outside that block.
A block means a part of code enclosed in braces ({}).
Scope based on these blocks is called block-level scope.

However, unlike other languages, JavaScript uses functions instead of blocks.
In JavaScript, a function can access all variables and functions defined within the scope where it is defined.

A global function can access all global variables and global functions.
On the other hand, an inner function defined inside another function can access all variables defined in its parent function and all other variables that the parent function can access.

// Declares x, y, and name as global variables.
var x = 10, y = 20;
// Declares sub() as a global function.
function sub() {
    return x - y;     // accesses global variables x and y.
}
document.write(sub() + "<br>");
// Declares parentFunc() as a global function.
function parentFunc() {
    var x = 1, y = 2; // declared with the same names as global variables, limiting the global variable scope.
    function add() {  // add() is declared as an inner function.
        return x + y; // accesses local variables x and y, not global variables.
    }
    return add();
}
document.write(parentFunc());

Function Hoisting

In JavaScript, function scope means that all variables declared inside a function are valid throughout the entire function.

However, this scope is applied in the same way even before a variable is declared.
This characteristic of JavaScript is called function hoisting.
In other words, all variable declarations inside a JavaScript function behave as if they were moved to the beginning of the function.

var globalNum = 10;     // declares globalNum as a global variable.
function printNum() {
    document.write("The value of globalNum before declaring the local variable globalNum is " + globalNum + ".<br>"); // ①
    var globalNum = 20; // declares globalNum as a local variable. // ②
    document.write("The value of globalNum after declaring the local variable globalNum is " + globalNum + ".<br>");
}
printNum();

At point ① in the example above, it is easy to think that variable globalNum points to the global variable.
However, inside JavaScript, the code is processed as if it were changed as follows by function hoisting.

Code after hoisting

var globalNum = 10;
function printNum() {
    var globalNum; // The declaration part is moved to the beginning of the function by function hoisting.
    document.write("The value of globalNum before declaring the local variable globalNum is " + globalNum + ".<br>");
    globalNum = 20;
    document.write("The value of globalNum after declaring the local variable globalNum is " + globalNum + ".<br>");
}
printNum();

At point ① in the example above, a local variable named globalNum has only been declared and has not yet been initialized.
Therefore, accessing variable globalNum at that time returns undefined because an uninitialized variable is being accessed.
The actual initialization of the variable occurs at point ②, where the variable is declared in the original code.

JavaScript automatically performs function hoisting, but it is best to declare variables at the beginning of the function block.