I would try to explain lexical scope in plain English. Wish me luck
Tags: beginners, javascript, webdev
Published: 2019-09-06 18:01:15

While writing an article on closures and IIFE some days back. I was trying to explain lexical scope in a short and simple way. I noticed the article was getting bigger and bigger so i just decided to write about lexical scope separately.  
In this article, i would try to explain the basics of lexical scope, what it means and give examples to help you understand how it works in JavaScript. No buzzwords...I promise.

Firstly, let's break down the word **"Lexical Scope"**.

## scope

We'll talk about the easy one first: **scope**.
In plain English, scope can mean:
- A boundary
- A region
- An environment

Or any other synonym you could think of.

Do you remember watching a tutorial where the instructor tells you a certain idea/topic is beyond the scope of the video?
Or when a team from another department is working on a project and you tell them to add a feature you think is cool and they tell you: "*That's beyond the scope of this project*".
Well i think you get the gist. Scope is simply a **region** where something is allowed to operate at a **given period of time**.

In Computer Science, this could mean a **region** where some data exists and can be accessed. This data could be something like a **variable**.

In a language like JavaScript, we could define a scope by creating a block using curly braces: `{...}`. We call this **Block Scope**. This means that variables declared inside this block can only be accessed within this **region**. This **region** covers everything inside it, including other child/inner blocks created within that region. 
In other words this region is `local` and its variables cannot be **directly accessed** from the outside world. So this could be called a **local scope**. 
Variables declared inside functions are in the **local scope** of the function.

```javascript
function doSomething() {
  let name = "john";
  console.log(name)
}

doSomething(); // Prints 'john'

// would produce a Reference error
// because name is local to doSomething() function's scope
console.log(name); 
```

Now, you might have heard of **Global Scope** before. Well, that's an environment which is not enclosed in a block. Every code in your Javascript environment has access to it. This is the open JavaScript environment. So the code below should work.

```javascript
let name = "john"; // In the global scope

function doSomething() {
  name = "James"
  console.log(name); // The function can access the global scope variable 'name'
}

doSomething(); // Prints "James"
console.log(name); // Can access 'name' too
```

One thing to note:
> A scope has access to its parent scope but the parent scope does not have direct access to variables declared in an inner scope.

The function has access to `name` because the function is declared in the global scope and `name` exists in the global scope. If name was declared inside the `doSomething()` function, then the code in the global scope cannot change the value of `name` directly because `name` is local to the function.

I believe you have a good understanding of what **Scope** means. It just simply means a **region** or **environment** where a variable exists and can be accessed or modified.

Now, let's talk about "**Lexical**"

## Lexical

To understand lexical, let's first look at the word from which it is derived from: **Lexicon**.
Lexicon was derived from the latin word: **"lexis"** which means **"word"**
In plain English:
> Lexicon simply means a dictionary. In order words, it means a vocabulary of a person's language. It is like a book where the meaning/definition of words are stored.

Whenever you want to find the meaning of a word, you go to the **lexicon**.
You don't look at where the word is used and guess what it means and its content or value. You always go the **lexicon**, where the word's purpose is **created** and clearly defined.

Now with that explanation:
> **Lexical** simply means something related to the lexicon. In other words, it means something related to words or vocabulary of a person's language. Something related to the creation or definition of words.

Let's talk about lexical scope.

## Lexical Scope

We have seen the meaning of the two words in plain English.
With that knowledge, let's define **Lexical Scope** in plain English:

> **Lexical Scope** simply means that the **region** in which a **word** exists is determined by where it was **defined** or **created**.

Other definitions would be: 

> **Lexical Scope** means that the meaning/value of a word can only be determined by the **region/environment** where it was created.

> **Lexical Scope** means that you don't directly outsource the meaning of a word to people from an outside **region** that uses the word. This is because lexical places emphasis on the origin on where it was created/defined.

Okay, i'll give an example.
Let's use the word: "Dance".
The word "dance" was created/defined in Britain. The British people know its meaning. This word exists in the scope in which it was created: "Britain". Wales is in Britain so Wales has access to this word (remember we already explained why above). So the Welsh people can update the meaning of this word to suit their local dialect. This is because they are inside the scope of Britain.

The Germans cannot directly come and change the meaning of this word. This is because the word was not created in Germany. So, if the Germans wanted to use the English word: **"dance"** and that word has not yet been created by Britain, that word would not be available no matter how hard they try. This would make no one to know the actual meaning of that word in Germany because the word doesn't exist in the **British Lexicon**. (Don't worry if this seems gibberish, i'll explain with code later on)

Since we're students of Science and not Linguists, let's replace **"word"** with **"variable"**.

Our new definition would be:

> **Lexical Scope** simply means that the **region** in which a **variable** exists is determined by where it was **defined** or **created**.

> **Lexical Scope** means that the meaning/value of a variable can only be determined by the region/environment where it was created.

> **Lexical Scope** means that you don't directly outsource the meaning of a variable to code from an outside region(block) that uses the variable. This is because lexical places emphasis on the origin on where the variable was created/defined.

So what lexical scope shows us is that a variable can only be used in the scope in which it was created and not where it was called.

Let's see how this works in code:

```javascript
function rideBritishBoat() {
  let boatName = "Queen's Dab"; // local variable
  return `Driving ${boatName}`
}

function rideGermanBoat() {
  const status = rideBritishBoat();
  return status;
}

rideGermanBoat();
```
The example above simulates a scenario where the Germans bought a boat from Britain....(You could swap it which ever country you want...no need to fight why i didn't mention some other country. These are just country names and not JavaScript libraries :stuck_out_tongue: ).
The `rideGermanBoat()` uses the `rideBritishBoat()`.
Since JavaScript uses lexical scope, when executing the `rideBritishBoat()` function, it goes to where it was **created** and gets the reference of the variable: `boatName`. So with lexical scoping, whenever `rideBritishBoat()` is executed, JavaScript goes inside the function's scope to look for the variables used in this function.

Note: The scope of the `rideBritishBoat()` function is its local scope and the global scope. The `rideGermanBoat()` is not in the lexical scope of the `rideBritishBoat()` function because `rideBritishBoat()` was not created inside it.

Now, let's change the example a bit:

```javascript
function rideBritishBoat() {
  return `Driving ${boatName}`; // Reference Error: boatName not defined
}

function rideGermanBoat() {
  let boatName = "Merkel's Dab";
  const status = rideBritishBoat();
  return status;
}

rideGermanBoat();
```

The above code fails. The `rideBritishBoat()` functions fails to be precise. It fails when trying to access `boatName` in the return statement.

**Why?**

This is because JavaScript uses lexical scope.
How this works is when it encounters `boatName` variable inside the `rideBritishBoat()` function, it **looks for** where the `boatName` variable was **created** in its **Scope Chain**. That is, all possible scope of that function which is the: **Local Scope** of the function, then it checks its enclosing scope in this case the **Global Scope**.

So that is how JavaScript checks for variables. It first checks the local block in which the current variable is used to know if it was declared there. If it wasn't, then it goes up to the enclosing scope and keeps going if it doesn't find a declaration till it reaches the top of the chain which is the **global scope**

There is one other type of Scoping called **"Dynamic Scoping"**.
The previous code would work in a language that supports dynamic scoping(e.g Lisp).
This is because in a dynamically scoped environment, the variable is checked at run-time. What is means is that when you execute `rideGermanBoat()` and execution gets to `rideBritishBoat()` the runtime environment checks for the value of `boatName` where the code is currently running. In this case it finds it, so no problem and the code works at expected and prints out `Driving Merkel's Dab`.

**Lexical Scope** is also called **Static Scope** because its the scope is determined at compile-time. Meaning it's environment/scope is fixed and can't just change. In other words, variables can only be called from within the block of code in which it was declared/created.

**Dynamic Scope** is called **dynamic** because its environment (outer scope) can change. In other words, variables can be called from outside the block which they are created.

So we could have another function that uses the `rideBritishBoat()` called `rideMauritianBoat()`:

```javascript
function rideMauritianBoat() {
  let boatName = "Flying Dodo's Dab";
  const status = rideBritishBoat();
  return status;
}

rideMauritianBoat();
```
In a dynamically scoped language, you can see the value of `boatName` variable inside `rideBritishBoat()` is dependent on the scope in which it is executed. As we can see that this scope can change, hence it is dynamic.
So inside `rideBritishBoat()`, it calls the `boatName` variable of `rideMauritianBoat()` which is outside its block scope. 

That's Dynamic Scoping and Lexical Scoping is the opposite.

But remember, JavaScript is not Dynamically scoped. This is just to show you the difference.

So lexical scoping checks for variables at compile-time (variables needs to be created and accessible in the scope/block it is used) while dynamic scoping checks for variables at run-time (variables might not be created in the scope when compiling but can be present when the function is running).

**Senior Devs be like: Dude!! JavaScript is not a compiled language!!**
Please, Let's leave that talk for some other day. Just try get to get the message i'm passing.
Okay, i'm pissed right now. Here's an exercise for you.

## Quick Exercise 

What would be the output of this function?

```javascript

function rideBritishBoat() {
  let boatName = "Queen's Dab";
  function rideWelshBoat() {
    boatName = "Welsh Royal Boat";
    console.log(boatName)
  }
  rideWelshBoat();
}

rideBritishBoat()
```

## Summary
The aim of this article was to explain **lexical scoping** in a simple way using basic grammar and short examples. If you noticed some words are in bold. Those are the key words to understand this concept. Plus, i have lots of alternate definitions of the same concepts. This was done for you to select which one sinks in easily for you. Different strokes for different folks :wink:

From what we've learnt above we can say that:

- A scope is an environment/region in which something (a variable) exists
- A scope can access its parents.
- A parent scope does not have direct access to variables declared in an inner scope.
- Lexical has do do with where a variable was declared/created.
- Lexical scope enforces finding variables from the scope/block they were created/declared and not the environment which they are running in.
- Dynamic Scope is the opposite of Lexical Scope.
- Dynamic scoping checks the variables from where they are running.


Thanks for reading.
I'll see you in the next post.