Understanding scope and hoisting in JavaScript

Understanding scope and hoisting in JavaScript

What is the scope?

In JavaScript, scope refers to the visibility and accessibility of variables. There are two types of scope: global scope and local scope.

A variable defined in the global scope is accessible from anywhere in your code. On the other hand, a variable defined in a local scope is only accessible within the block of code in which it is defined.

Declaring variables in the global scope

In JavaScript, any variables declared outside of a function are automatically defined in the global scope.

For example:

let globalVariable = "I am a global variable";

function foo() {
  console.log(globalVariable); // Output: "I am a global variable"
}

foo();

In the code above, the variable globalVariable is defined in the global scope and is therefore accessible from within the foo() function.

Declaring variables in a local scope

To define a variable in a local scope, you can use the let or const keywords within a block of code.

For example:

function foo() {
  let localVariable = "I am a local variable";
  console.log(localVariable); // Output: "I am a local variable"
}

foo();
console.log(localVariable); // Output: Uncaught ReferenceError: localVariable is not defined

In the code above, the variable localVariable is defined within the foo() function and is therefore only accessible within that function. If you try to access the localVariable outside of the foo() function, you will get a reference error.

Differences between let, var, and const based on the scope.

In JavaScript, you can declare variables using the let, var, and const keywords.

  • let is a keyword that is used to declare variables in a local scope. Variables declared with let can be reassigned, but cannot be redeclared in the same scope.
  • var is a keyword that is used to declare variables in either the global or local scope. Variables declared with var can be reassigned and redeclared within the same scope.
  • const is a keyword that is used to declare variables in a local scope. Variables declared with const cannot be reassigned or redeclared within the same scope.

It is generally recommended to use let and const over var when declaring variables in JavaScript. This is because let and const provide better control over the scope and mutability of your variables.

Here is an example of using let and var to declare variables in both the global and local scope:

// Global scope
var globalVariable1 = "I am a global variable";
let globalVariable2 = "I am also a global variable";

function foo() {
  // Local scope
  var localVariable1 = "I am a local variable";
  let localVariable2 = "I am also a local variable";
  
  console.log(globalVariable1); // Output: "I am a global variable"
  console.log(globalVariable2); // Output: "I am also a global variable"
  console.log(localVariable1); // Output: "I am a local variable"
  console.log(localVariable2); // Output: "I am also a local variable"
}

foo();

console.log(globalVariable1); // Output: "I am a global variable"
console.log(globalVariable2); // Output: "I am also a global variable"
console.log(localVariable1); // Output: Uncaught ReferenceError: localVariable1 is not defined
console.log(localVariable2); // Output: Uncaught ReferenceError: localVariable2 is not defined

In the code above, globalVariable1 and globalVariable2 are defined in the global scope and are therefore accessible from within the foo() function. localVariable1 and localVariable2 are defined within the foo() function and are therefore only accessible within that function. If you try to access localVariable1 or localVariable2 outside of the foo() function, you will get a reference error.


What is hoisting?

Hoisting is a term used to describe the behavior of variable declarations in JavaScript. When a variable is declared, it is automatically assigned to the top of the current scope. This is called hoisting.

For example:

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

var x = 5;

In the code above, the declaration var x = 5; is hoisted to the top of the global scope, which means that the value of x is undefined until the declaration is encountered during execution.

It’s important to note that hoisting only affects the declaration, not the assignment. This means that the value of the variable is not hoisted along with the declaration.

How hoisting works with function declarations

Function declarations are also hoisted in JavaScript. This means that you can call a function before it is declared in your code.

For example:

foo(); // Output: "Hello, world!"

function foo() {
  console.log("Hello, world!");
}

In the code above, the function foo() is hoisted to the top of the global scope, which means that it is accessible from anywhere in the code.

How hoisting works with function expressions

Unlike function declarations, function expressions are not hoisted. This means that you cannot call a function defined with a function expression before it is declared in your code.

For example:

bar(); // Output: Uncaught TypeError: bar is not a function

var bar = function() {
  console.log("Hello, world!");
};

In the code above, the function bar() is not hoisted to the top of the global scope. Instead, it is treated as a variable and is assigned the value of the function expression when the code is executed.


Practice Exercise

  1. In the following code, what will be the output?
console.log(x);

var x = 5;

function foo() {
  console.log(y);
  
  let y = 10;
}

foo();
  1. Consider the following code, what will be the output of the code?
function foo() {
  let x = 5;
  
  if (true) {
    let x = 10;
    console.log(x); // Output: 10
  }
  
  console.log(x); // Output: 5
}

foo();
  1. You are building a shopping cart for an online store and want to keep track of the total number of items in the cart. You declare a global variable totalItems and update its value every time an item is added or removed from the cart. Is this a good approach to solving this problem? Why or why not?
  2. You are working on a web application that allows users to input and submit data through a form. You want to prevent users from submitting the same data twice within a short time period. You declare a global variable lastSubmissionTime and check its value every time the form is submitted. Is this a good approach to solving this problem? Why or why not?
  3. You are building a game that keeps track of the player’s score. You want the player’s score to be reset to 0 every time they start a new level. You declare a local variable score within the startLevel() function and assign it a value of 0. Is this a good approach to solving this problem? Why or why not?
  4. You are building a chat application and want to keep track of the messages that have been sent by each user. You declare a global object messages and add a new property to it for each user, with the value being an array of the messages sent by that user. Is this a good approach to solving this problem? Why or why not?
  5. You are building a data visualization tool and want to allow users to select different data sets to view. You declare a global variable currentDataSet and update its value every time the user selects a new data set. Is this a good approach to solving this problem? Why or why not?

Understanding scope and hoisting are important in JavaScript. By keeping track of the scope of your variables and understanding how hoisting works, you can ensure that your code is organized and easy to understand and avoid common pitfalls to writing code that is easier to understand and maintain.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.