Web
JavaScript
Scope

Scope

What is Scope?

  • JavaScript's scope has unique characteristics that distinguish it from other languages.
  • The scope of a variable declared with the var keyword behaves differently from that of a variable declared with let or const.
  • Scope is closely related to variables and functions.
  • A variable's scope, i.e., the range within which it can be accessed by other code, is determined by where it is declared. This applies not only to variables but to all identifiers.
    → All identifiers (such as variable names, function names, and class names) have a valid range determined by their declaration location. This is called scope.
    → Scope refers to the range in which an identifier is valid.

var x = "global";
 
function foo() {
  var x = "local";
  console.log(x); // (1)
}
 
foo();
console.log(x); // (2)
  • The JavaScript engine needs to determine which variable to reference when two variables have the same name. → Identifier resolution
  • The JavaScript engine determines which variable to reference using scope. Scope is the rule the engine follows when searching for identifiers.
  • Without the concept of scope, variables with the same name would conflict, meaning they could only be used once throughout the entire program.

var x = "global x";
var y = "global y";
 
function outer() {
  var z = "outer's local z";
 
  console.log(x); // (1) global x
  console.log(y); // (2) global y
  console.log(z); // (3) outer's local z
 
  function innter() {
    var x = "innter's local x";
 
    console.log(x); // (4) innter's local x
    console.log(y); // (5) global y
    console.log(z); // (6) outer's local z
  }
 
  innter();
}
 
outer();
 
console.log(x); // (7) global x
console.log(z); // (8) ReferenceError: z is not defined
  • The inner function is a nested function inside outer.
  • The local scope created by outer is the parent scope of the local scope created by inner.
  • The parent scope of outer's local scope is the global scope.
  • All scopes are hierarchically connected, and the top-level scope of all local scopes is the global scope. → This hierarchical connection is called the scope chain.
  • When referencing a variable, the JavaScript engine searches through the scope chain, starting from the scope of the referencing code and moving upwards.
    → This allows lower scopes to reference variables declared in higher scopes.

Lexical Environment

  • The scope chain is a unidirectional chain of lexical environments within an execution context.
  • The global lexical environment is created as soon as the code is loaded, and a function's lexical environment is created as soon as the function is invoked. (Related to execution context)

var x = 1;
 
function foo() {
  var x = 10;
  bar();
}
 
function bar() {
  console.log(x);
}
 
foo(); // (1) ?
bar(); // (2) ?
  • Programming languages typically determine a function's parent scope in one of two ways:
    1. Determining the function's parent scope based on where it is called. → Dynamic scope
    2. Determining the function's parent scope based on where it is defined. → Lexical scope or static scope
  • JavaScript, like most programming languages, follows lexical scope.
  • The bar function is defined in the global scope. -→ Both (1) and (2) result in 1.