# 5.1: Program Lifecycle and State

## Learning Objectives

By the end of this lesson, you should be able to:

* Explain the difference between a global and local variable.
* Understand when and why to use global variables.
* Declare and use global variables.
* Briefly explain "function scope".

## Introduction

{% embed url="<https://www.youtube.com/watch?v=oxxwcMJN8ec>" %}

Our programs have so far handled ephemeral *(temporary)* data that exists only while `main` or the relevant parent function is running. Now we will handle data that ***persists across*** runs of `main`, and functions in our app in general.

## Scope Hierarchy

Variables defined "higher up" the scope hierarchy will be available to reference in "lower" scopes, but not the other way around.

Globally-defined variables can be accessed in function scope and block scope, and anywhere else in the program, hence *global.* Variables defined in block scope can only be accessed within that block.

![](https://www.stevethedev.com/storage/app/uploads/public/5aa/d54/a47/5aad54a47d2e0123286333.png)

### Global Scope

Any variables defined outside of a function or a block of code exists in global scope. This include function definitions. So `main`, and any other functions we have written are in global scope. This allows us to *call* the function inside other functions or nested blocks of code.

So far, we have been creating variables inside of a function or a block of code, but nothing is stopping us from creating a variable at the "top level" of `script.js`, in global scope.

### Global Variables

We will use our dice game to demonstrate the value of data *persistence*. In a dice game, we may want to keep track of the "bank roll" or score for the duration of our game. We need a syntax to store a value (bank roll in this case) that we read and update when `main` runs and is also available ***the next time*** `main` runs.

The syntax we will use is called "**global variables**". Global variables in SWE Fundamentals will persist from **when the program loads** in the browser to when **we close the tab or reload the page**. Try running the following code line by line in Chrome DevTools. The variable `number` persists across our commands, but when we refresh the page, `number` is no longer available. Similarly, our global variable data will persist across function calls, but **not across browser sessions**.

```javascript
var number = 5;
number = number * 2;
number;
```

### Function Scope

Sensibly, variables declared within the function definition exist in function scope. When your program first loads, the functions are defined, but are not yet *executed* until a function call is made. You can verify this by opening the console, and checking the value of `main`.

Understand that the function `main` that we have been using is defined in the **global scope**, so the browser knows what it is, but attempting to access any variables defined within the function via the console will result in an error.

Once the function has been executed, the program returns to the scope from when the function was called, and all the variables declared and used by the program within the function are effectively forgotten. **Only the return \_value**\_\*\* persists\*\*. This return value, as you have already been doing before, is stored into another variable.

Consider the example below where `convertKmToMiles(input)` is assigned to `myOutputValue` (line 6).

```javascript
var convertKmToMiles = function (input) {
  return input / 1.609;
};

var main = function (input) {
  var myOutputValue = convertKmToMiles(input);
  return myOutputValue;
};
```

Different functions have their own scope. **Variables declared in one function are not accessible in another function**. Hence it is possible to re-use variable names in different functions, or more generally, in different scopes. However, you are strongly advised against this.

In contrast to "global variables" then, "local variables" are variables created within a smaller scope within the global scope.

Recall the `main` function we've been using so far. In this function, `myOutputValue` only exists during the execution of `main`, corresponding to 1 Submit-button click.

If we try to inspect the value of `myOutputValue` in the console after clicking Submit, `myOutputValue` doesn't exist.

```javascript
myOutputValue;
```

This behaviour is common to all variables declared inside a function, and a demonstration of **"function scope"** in JavaScript. This means that variables declared in a function are available for the life of that function, then they disappear.

### Block Scope

Block scoping applies to any variable defined in a block of code within a pair of `{}`. In SWE Fundamentals, this is mostly blocks of code defined by if-statements.

Similar to Function Scope, once the program exits the block and returns to a higher scope, variables declared within the block are effectively forgotten and inaccessible.

## Global State

{% embed url="<https://www.youtube.com/watch?v=xVIAh_o4mPc>" %}

Building on the logic above, global variables can thus be used as a "global state" of sort.

This is the idea that we can **declare variables outside** of functions and have those variables ***persist across*** function calls, keeping their values intact.

In this example, we persist `papayaCount`, in this case a count of the number of times a user has clicked Submit. `papayaCount` is part of `myOutputValue`, which shows the user how many times they have clicked Submit.

```javascript
// Variables in the Global Scope - papayaCount and main
var papayaCount = 0;
var main = function (input) {
  // Variables in the Function Scope (of the main function) - myOutputValue
  papayaCount = papayaCount + 1;
  var myOutputValue = 'You have ' + papayaCount + ' papayas';
  return myOutputValue;
};
```

### Global Variables for Dice Guessing

{% embed url="<https://youtu.be/X-b_LJAJIsU>" %}

Bank roll or score is an application of the global "counter" variable to our dice game. In the following example, we increment `bankRoll` every time the player correctly guesses the dice roll.

```javascript
var bankRoll = 10;

var main = function (input) {
  var randomDiceNumber = rollDice();

  var myOutputValue = 'you lose. current bank roll: ' + bankRoll;

  if (randomDiceNumber == input) {
    bankRoll = bankRoll + 1;

    myOutputValue = 'you win. current bank roll: ' + bankRoll;
  }

  return myOutputValue;
};
```

## Exercises (Base)

### Follow Along

Follow along with the videos and duplicate the code.

### **App Setup**

For the following exercises, start with the SWE Fundamentals Starter Code template and replace the code in `script.js` with the following dice game code.

```javascript
var rollDice = function () {
  // produces a decimal starting from 0 and ending BEFORE 6 (5.999999...)
  var randomDecimal = Math.random() * 6;

  // take off the decimal -> 0 to 5
  var randomInteger = Math.floor(randomDecimal);

  // it's a number from 0 - 5 ... add 1 -> 1 to 6
  var diceNumber = randomInteger + 1;

  return diceNumber;
};

var main = function (input) {
  var randomDiceNumber = rollDice();

  var myOutputValue = 'you lose';

  if (randomDiceNumber == input) {
    myOutputValue = 'you win';
  }

  return myOutputValue;
};
```

### **Last Roll**

Create a version of the dice game that tells the user what their previous dice roll was.

#### Sample Output

```
Your last roll was 4. You just rolled a 3. You guessed 3. You win!
```

### **Win / Loss**

As the user continues to play the game, tell them what their current win / loss percentage is.

#### Sample Output

```
You win 23.5% of the time. You just rolled a 4. You guessed 3. You lose!
```

## Exercises (More Comfortable)

### **Most Rolled**

Keep track of the number that's rolled the most times.

#### Sample Output

```
You just rolled a 4. 2 is the number you roll the most. You guessed 3. You lose!
```

### **Guessing**

If the player guess is off-by-1 they win 1 point. If the player guess is exact they win 2 points.

### **Advanced Guessing**

The player guess can be off by up to 4. If the player guess is off-by-4 they win 1 point. Off-by-3, 2 points, off-by-2, 3 points, off-by-1, 4 points, exact, 5 points.

## Reference Solutions

[Click here ](https://github.com/rocketacademy/fundamentals-starter-code/blob/8.1-refSolns-moreComfortable/script.js)to view the reference solution. Please only refer to the reference solution after you have attempted the exercise. Note that there are many ways to implement the exercise and the reference solution is only 1 way.
