JavaScript: Variable Scope
You may remember from the previous section that parameters passed to a function only exist for the lifetime of that function. When the end of the function is reached, the parameters are lost (at least, from the perspective of that function).
Scope determines which parts of your code can access a given variable. Some variables can be accessed from anywhere but in order to help us keep our code tidy - some variables can only be accessed from within a certain part of your code.
Variables have one of two scopes.
-
Global variables: These variables can be accessed from anywhere in your code. You can create them once when you start your script and any function or part of your code can access them.
-
Local variables: These variables can only be accessed from a specific part of your code, usually just within a single function.
Global Scope
Global variables are variables that are defined outside of any curly braces. They often appear near the top of a JavaScript file so that it’s easier to see what’s available globally in your script.
Global variables can be accessed from anywhere in your code. i.e. if you write to a global variable from inside a function – it will still change that value for the rest of your app.
Global variables are useful, but because they can be changed anywhere – they should be used carefully. Otherwise, things can get confusing when your code grows large.
The following code creates a global variable called counter. We then create a function that operates on the global variable so that any of your code can increment the counter.
var counter = 0;
function incrementAndLogCounter() {
counter += 1; // counter = counter + 1;
console.log(counter);
}
console.log(counter); // Prints 0
incrementAndLogCounter(); // Prints 1
incrementAndLogCounter(); // Prints 2
console.log(counter); // Prints 2Local Scope
Local variables are all variables declared within a function. Whenever you declare a variable using ‘var’ inside of a function, that variable exists inside that function only. When the function ends, the variable is destroyed.
I like to call these “Function Scope” variables - as they are essentially bound to the function they are created in.
function generateName(isMale) {
if ( isMale ) {
var name = "John";
} else {
var name = "Joanna";
}
console.log(name);
}
generateName(true); // Prints "John"
generateName(false); // Prints "Joanna"
console.log(name); // Error!Advanced Topic: Block Scope
ECMAScript 6 recently added yet another way to declare variables. You can now use the ‘let’ statement to declare a variable which exists solely within the current block.
A block is a section of code surrounded by {curly braces}. As ‘let’ only exists within the current set of curly brackets, it’s even more limited scope than var.
I like to call these “Block Scope” variables. We won’t be using ‘let’ variables throughout this course - but you are more than welcome to use them if you are comfortable with doing so.
function generateName(isMale) {
if ( isMale ) {
let name = "John";
} else {
let name = "Joanna";
}
console.log(name);
// Error: name was destroyed at the end
// of the ‘if/else’ blocks.
}Scope Collision
If you declare a local variable within a function or a block, it will “hide” the variable declared in global scope.
This can often be confusing and so it’s usually just something you want to avoid.
That’s another reason why global variables are best avoided where possible – if you have many files containing lots of global variables, you don’t necessarily know all of their names.
var name = "John";
function doSomething() {
var name = "Alex";
console.log(name);
}
doSomething(); // Prints "Alex"
console.log(name); // Prints "John"This can sometimes be hard to catch and is a little confusing to understand. The important lesson here at the moment is that if you create global variables that you want to use anywhere in your code - it’s a good idea to give them a descriptive and long name so that it’s less likely to clash with other variables used in functions.
For instance, if we wanted to make the player score a global variable we might want to call it gamePlayerScore instead of just score.