DEV Community

Cover image for Scope - JavaScript Core Concepts
Angeline Wang
Angeline Wang

Posted on

Scope - JavaScript Core Concepts

The Section 2: Functions & Methods of my JavaScript Core Concepts Series is divided into 6 Parts:

Part 1 Functions
Part 2 Classes
Part 3 Methods
Part 4 Callback Functions
Part 5 Scope
Part 6 Hoisting

JavaScript Scope

Part 1 What is Scope?

= Visibility of Functions & Variables in different parts of your code during Runtime
→ Part of the code where it is available

= Determines Variables’ accessibility (differs depending on programming language)
Variables defined inside a Function
→ Not accessible from outside Function

But can be used as many times
→ As their Function is used throughout Program

What does Scope look like in action?

= Working w/ Variables & Scope comes intuitively to most developers
→ Mental models help developers understand when something can be off limits

What determines a Variable's Scope?

= Location of Variable Declaration

Part 2 JavaScript Scope Types

1. Global Scope

What is Global Scope?

= Outermost scope
→ Any variables declared in thai scope become global variables
→ And are accessible from anywhere in the program

Code Example

const name = “Angeline”;

function sayHi() {
    console.log(`Hi ${name}`);
}

sayHi();
Enter fullscreen mode Exit fullscreen mode

= Variable name is Global
→ Defined in Global Scope
→ Accessible throughout the Program

Use Case of Global Scope

= Discouraged in JavaScript
→ Can potentially be overwritten by other Scripts
→ Or from elsewhere in the Program

Global Variable Assignment w/in a Function

= Global Variable assigned a different Value inside a Function
→ Value only retained in boundaries of same Function

Outside the function

= The variable has as different value
→ One declared in the global scope
→ Will not get an error for using the same Variable Name

Undeclared Variables

= JS will not stop use of undeclared variables
→ Any point: You can assign a value to a variable without using const let or var
→ When this is done: Engine tries to look for the variable bubbling up to the global scope

If does not find it there:
= Creates a Global Variable for you

2. Local Scope

= Local scope has 2 variations:

#1 (Old) Function scope

= Variables can be accessed in boundaries of the function in which they are defined

var Variables
= Have the Old Function Scope
= Are either Globally Scoped, or Locally Scoped to Function defined in
→ Thus, it is not affected by Block Scope, so you cannot declare a new Locally Scoped Variable with the same name as one declared in the Global Scope

#2 (New) Block Scope – introduced w/ ES6

= Function scope is a special type of a block scope
= Variables can be accessed in the block in which they are defined
→ A block is separated by { and }

let & const Variables have Block Scope
= Creates a new, local scope for any block they’re declared in
→ Can also define standalone code blocks in JS
→ They similarly delimit a scope

New Block Scope Rules
  1. Variables w/ Same Name
    = Can be specified at multiple layers of nested Scope

  2. Local Variables
    = Gain priority over Global Variables

  3. Local & Global Variable declared w/ Same Name
    Local Variable takes precedence
    = Declare a Local Variable & a Global Variable with same name

Local variable takes precedence
= When you use it inside a Function or Block
→ This behaviour is called Shadowing

  1. Variables declared inside a Block = Belong to that particular Block → And become Local Variables

3. Lexical (Static) Scope

What is Lexical Scope?

= Created when a new Function is created
→ A new Lexical Scope is created

What is the purpose of Lexical Scope?

= Allows inner functions to access the scope of outer functions

= To find a Variable, the JS interpreter uses Lexical Scope:

  1. Works starting from the currently Executing Scope

  2. Works its way out until it finds the Variable in question

  3. If Variable is not found in any Scope
    = An exception is thrown

Lexical Scope of Variables

= Static/Lexical Structure of a Program
→ Determines Variable Scope

Lexical Scope of Functions

= No matter where a Function is called from
→ No matter how it’s called: Its Lexical Scope depends only on where the function was declared

What is Shadowing?

= Inner Variable shadows the outer
→ This is the mechanism used
→ For JS interpreter to find a particular Variable

How does Shadowing work?

  1. Starts at innermost scope being executed at the time

  2. Continues until 1st match is found
    = No matter if there are other variables with same name in outer levels or not

  3. Even with same name
    = Local variable does not overwrite the global one after execution of function
    → And means that 2 different variables are created
    → BUT not always the case

  4. If the local variable is assigned a value without the var keyword, it becomes a global variable
    = Simply as a value assignment
    → This will overwrite the global variable with the same name
    → And the global variable will be officially reassigned

Nesting

= Function & Block scopes can be nested
→ Where there are multiple nested scoped:
Variable is accessible within its own scope (parent function)
Or from inner scope
→ Outside of its scope:
Variable is inaccessible

Need Variable inside a Function

  1. Engine looks for it in Scope of current Function

  2. Goes 1 level up in Function containing it

  3. If not found, continues to go up
    = Until it reaches the Global Scope

  4. If Variable not found there
    = Will get a ReferenceError

Assignment w/o Declaration

Prevent Overwriting Global Variables

= Always declare your local variables
→ Before you used them

Example
= Any variable declared with var keyword inside a function
→ Is a Local Variable: It is best practice to declare your variables

Strict Mode

= In strict mode, it is an error if you assign a value to a variable without first declaring the variable

Part 4 Best Practice

= Do not pollute the global scope

If a Variable is meant to be globally used:
= Declare it in the global scope
→ So intentions can be clear

If it is not meant to be globally used:
= Keep it inside the scope it is used in

How to master JS?

= Must look to build on top of those existing mental models
→ AND go into the specifics

= Though it is possible to write fine code without deep understanding of scope
→ Only those that have put in the time to read the small print
→ Can avoid pitfalls in trickieset of situations

Part 5 Hoisting Priority

= Hoisting happens in this order:

  1. Function Declarations

  2. Variable Declarations
    → Class Declarations are hoisted as Variables

Variable (& Class) Assignments
= Are not Hoisted
→ Will instead overwrite Declarations after code is read in cascading order

Resources for Further Exploration:

Sitepoint: Demystifying JavaScript Variable Scope and Hoisting By Ivaylo Gerchev

Hackernoon – Understanding JavaScript: Scope – By Alexander Kondov

Top comments (0)