Block & Function Scope

Open the project folder

In our starter files, open the index.html page from this lessons folder:

09.Scope-Hoisting-Closures > 03.Block-function-scope

Starter file code

This lesson begins with the same example we previously looked at:

var score = 0;

function updateScore() {
  score++;
  var bonus = 10;
  console.log('inside function' + bonus3);
  if (bonus) {
    console.log('inside if statement: ' + bonus);
    var numbers = [1, 5, 8, 2];
    var i = 0;
    while (i < numbers.length) {
      var bonus3 = 30;
      console.log(bonus);
      i++;
    }
  }
}

updateScore();

Function scope

With this example, the nesting is contained inside of a function. And functions behave differently to other statement blocks. Going forward, when mentioning blocks, we are referring to code surrounded in curly braces such as if statements, while, and for loops.

With a function like this, we cannot access the variables declared inside it, from outside the function, such as the bonus3 variable:

// ...
  }
}
updateScore();
console.log(bonus3);

ReferenceError: bonus3 is not defined

Even if these variables are declared using let or const, it will be the same result. This is how a function behaves, it has its own scope.

Block scope

This is not as simple with blocks though. To see this, change this example from a function to any block, such as an if statement:

if(score === 0) {
  score++;
  var bonus = 10;
  console.log('inside function' + bonus3);
  if (bonus) {
    console.log('inside if statement: ' + bonus);
    var numbers = [1, 5, 8, 2];
    var i = 0;
    while (i < numbers.length) {
      var bonus3 = 30;
      console.log(bonus);
      i++;
    }
  }
}
// updateScore();
console.log(bonus3);

The bonus3 variable is now available, and the same for others such as bonus.

We can see that blocks behave differently to functions regarding scope, these block statements do not have their own scope.

Using const and let

Or do they? Well as a JavaScript developer, we now have a choice depending on how we declare our variables.

Variables declared with var behave like this, but const or let will scope them to the surrounding block.

If we wanted to ensure bonus was not available outside this if statement, we can change it to use const or let, which will cause an error if we try to access these again with our log:

Uncaught SyntaxError: Unexpected identifier 'score'

With functions we don’t have this choice, but blocks give us the flexibility to decide.