5.1: Program Lifecycle and State
Last updated
Last updated
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".
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.
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.
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.
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.
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).
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.
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 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.
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.
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.
Follow along with the videos and duplicate the code.
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.
Create a version of the dice game that tells the user what their previous dice roll was.
As the user continues to play the game, tell them what their current win / loss percentage is.
Keep track of the number that's rolled the most times.
If the player guess is off-by-1 they win 1 point. If the player guess is exact they win 2 points.
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.
Click here 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.