Scope and the Scope Chain in JavaScript

Scoping – where do variables live? – Where can we access a certain variable?

Notes from JS Udemy Course

JS is a high level, object oriented multi paradigm programming language

Lexical scoping – scoping is controlled by placement of functions and blocks in the code

Scope is the space or environment in which a certain variable is declared.

There are 3 main types of scope for variables:

Global scope

Function scope

Block scope

The Scope of a variable, is the region of our code where a certain variable can be accessed.

Scope Chain in JavaScript

I asked Chat GPT “what is scope chain in JavaScript?”

A scope chain in JavaScript refers to the hierarchical order of scopes, with each scope having access to its own variables and those of its parent scopes.

This hierarchy is established based on where functions and blocks are physically located within the code (lexical scoping).

When a variable is referenced in JavaScript, the engine looks for the variable in the current scope.

If it doesn’t find it there, it moves up the chain to the parent scope. This process continues all the way up to the global scope if necessary. If the variable isn’t found in the global scope, a ReferenceError is thrown.

Here’s a simple example to demonstrate the concept:

let globalVar = "global"; // global scope

function outer() {
    let outerVar = "outer"; // outer function scope

    function inner() {
        let innerVar = "inner"; // inner function scope

        console.log(innerVar); // "inner", found in inner scope
        console.log(outerVar); // "outer", not found in inner scope but found in outer scope
        console.log(globalVar); // "global", not found in inner or outer scopes but found in global scope
    }

    inner();
}

outer();


In the above example, the inner function’s scope chain includes the inner scope, the outer scope, and the global scope. The outer function’s scope chain includes the outer scope and the global scope. The global scope is at the top of every scope chain.

The scope chain is fundamental to understanding variable lookup and closure behavior in JavaScript.

Hoisting in JavaScript

I asked chatgpt to explain hoisting to me:

In JavaScript, hoisting is a behavior in which variable and function declarations are moved to the top of their containing scope during the compile phase, before the code has been executed. This means you can use a variable or function before it’s been declared in the code.

However, it’s crucial to note that while the declarations (not initializations) are hoisted, the assignments are not. This is why a variable declared and initialized after it’s used will return undefined.

Here’s an example of hoisting with variables:

javascriptCopy codeconsole.log(myVar); // Output: undefined

var myVar = 5;

console.log(myVar); // Output: 5

In this example, the declaration (var myVar) is hoisted to the top of the scope, but the assignment (myVar = 5) is not. That’s why the first console.log outputs undefined, and the second outputs 5.

Now, let’s see an example with functions:

console.log(myFunction()); // Output: This is hoisted!

function myFunction() {
  return "This is hoisted!";
}

Here, the entire function declaration (including the body) is hoisted, so you can call the function before it's declared in the code.

However, if we use function expressions and try to call it before it's defined, it will return undefined because only declarations are hoisted, not initializations:


console.log(myFunction); // Output: undefined

var myFunction = function() {
  return "This is not hoisted!";
}

In JavaScript ES6, let and const were introduced, which have different scoping rules from var. While var is function-scoped, let and const are block-scoped. However, they too are hoisted, but due to a mechanism known as the Temporal Dead Zone (TDZ), you cannot access them before declaration.


console.log(myVar); // Output: undefined
console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization

var myVar = 5;
let myLet = 10;

In this code, trying to log myLet before it's declared results in a ReferenceError, while myVar is undefined due to the hoisting and the difference in behavior between var and let/const.

Then I asked Bard:

JavaScript hoisting is a concept that refers to the fact that variable declarations are moved to the top of their scope before the code is executed. This means that you can access a variable even if it is declared after the line of code where you first try to use it.

For example, the following code will print “Hello World!” even though the message variable is declared after the line where it is first used:

JavaScript

console.log("Hello World!");
var message = "Hello World!";

This is because the JavaScript engine will hoist the variable declaration to the top of the scope, before the code is executed. This means that the variable will be defined and accessible even though it is declared after the line where it is first used.

It is important to note that hoisting does not affect the value of the variable. In the example above, the value of the message variable will still be “Hello World!” even though it is declared after the line where it is first used.

Hoisting can be a useful concept to understand, but it can also lead to errors if you are not careful. For example, the following code will throw an error because the message variable is not defined when it is first used:

JavaScript

var message = "Hello World!";
console.log(message);

This is because the message variable is not defined until after the line where it is first used. To avoid this error, you should always declare variables before you use them.

Here are some tips for avoiding errors when using hoisting:

  • Always declare variables before you use them.
  • Use the const keyword to declare constant variables.
  • Use the let keyword to declare local variables.
  • Use the strict mode to prevent errors from being thrown when variables are not declared.

I hope this explanation of JavaScript hoisting was helpful. Please let me know if you have any other questions.

Leave a comment