Manage scope
Hey ,
I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.
Please upgrade (use this link) access this content.
I'm super eager to help you learn more!
Hey ,
I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.
Please upgrade (use this link) access this content.
I'm super eager to help you learn more!
“Scope” is a name given to an environment that contains variables. If you can access a variable, we say the variable is within scope. If you cannot access a variable, we say the variable is not in scope.
There are five kinds of scopes in JavaScript:
In this lesson, you’ll learn the first four kinds of scope. We’ll cover closures in a later module.
You create a variable in the global scope if you declare the variable outside all functions and curly braces ({}
). These variables are called global variables.
const globalVariable = 'some value'
Global variables can be used everywhere in your code. They can be used in any functions.
const hello = 'Hello world!'
function sayHello () {
console.log(hello)
}
console.log(hello) // 'Hello world!'
sayHello() // 'Hello world!'
If you hear the term local scope, it means the variable is not in a global scope. Local scope can mean function scope, block scope, or even lexical scope.
If you create a variable in function, the variable is in a function scope.
function someFunction () {
const functionVariable = 'some value'
}
You can use a function-scoped variable anywhere inside the function.
function someFunction () {
const functionVariable = 'some value'
console.log(functionVariable) // This will log 'some value'
}
someFunction()
But you cannot use the variable outside the function.
function someFunction () {
const functionVariable = 'some value'
console.log(functionVariable) // This will log 'some value'
}
console.log(functionVariable) // ReferenceError: functionVariable is not defined
A block is a set of code contain within curly braces ({}
). If you create a variable inside curly braces, that variable is scoped to the block.
Examples of blocks include:
for
loopsif
statement// For loop
for (const item of items) {
// item is block-scoped
}
// if statement
if (time === '12pm') {
const chimeCount = 12 // chimeCount is block-scoped
}
// A block
{
const name = 'Zell' // name is block-scoped
}
Block scope only applies to variables created with const
and let
. It does not apply to variables created with var
.
Variables created with var
are always scoped to its nearest function. In the example below, you can see that hello
ignores the block scope.
{
var hello = 'Hello world!'
console.log(hello) // 'Hello world!'
}
console.log(hello) // 'Hello world!'
This is why you should not create variables with var
anymore. Always use const
or let
.
You can use a variable after you created it. But you cannot use the variable before you created it.
This behavior is called lexical scope.
console.log(laugh) // ReferenceError: can't access lexical declaration `laugh' before initialization
const laugh = 'haha'
You can have functions in functions. When do this, you create a nested scope.
// Global scope
const outerFunction = _ => {
// outerFunction scope
const innerFunction = _ => {
// innerFunction scope
}
}
outerFunction
and innerFunction
outerFunction
can be used in innerFunction
, but not in the global scopeinnerFunction
can only be used in inner functionIt’s easy to visualize scopes with a one-way glass—you can see the outside, but people from the outside cannot see you.
If you have scopes within scopes, visualize multiple layers of one-way glass.
You can use variables with the same name if they exist in different scopes. If this happens, JavaScript uses the variable closest to the current scope.
const sayName = name => {
console.log(name)
}
const name = 'Zell'
sayName('Vincy') // Vincy
Each function you create has their own scope. Variables declared in one function cannot be transferred to another function.
In the example below, two
does not have access to varOne
, even though two
called one
.
function one () {
const varOne = `I'm part of one`
}
function two () {
one()
console.log(varOne) // Error, varOne is not defined
}
Here are three rules for managing scopes:
First: Avoid having too many global variables. If you have too many global variables, you may get a variable-name collision (where two variables use the same name).
If variables are declared with let
or const
, you’ll get an error. If variables are declared with var
, the second variable overwrites the first variable (which generates hard-to-find bugs).
Second: Keep variables scoped to the function they need.
// Don't do this
const prize = 'playstation'
function announceWinner(name) {
console.log(name + ' won a ' + prize)
}
// Do this
function announceWinner(name) {
const prize = 'playstation'
console.log(name + ' won a ' + prize)
}
Third: Don’t be afraid to hoist variables to a higher scope if needed.
Let’s say you have this:
function sayName (name) {
console.log(name)
}
function shoutName (name) {
console.log(name + '!')
}
sayName('Zell') // Zell
shoutName('Zell') // Zell!
Normally, you’d want to keep name
variable within each of these functions. But sometimes, you will want to hoist name
to a higher scope.
const name = 'Zell'
function sayName () {
console.log(name)
}
function shoutName () {
console.log(name + '!')
}
sayName() // Zell!
shoutName() // Zell!
This one is hard to explain with simple examples. You’ll see why I create this rule when you create dots for the carousel later (next module).
Here’s a simple order I follow: