JavaScript Lexical Scope
Tags: javascript, lexicalscope, scopechain, scope
Published: 2023-08-02 15:47:25

## INTRO
Lexical scoping, also known as static scoping. It is one of the important concept in Javascript. It helps to understand the variable accessibility (how and where we can access the variables at different level of scopes), avoid variable naming conflicts and to write organised and maintainable code. Due to lexical scope the functions may access all variables from their parent scopes up to the global scope, but no scope may access any variables from the functions defined inside it.

## DEFINITION
Lexical Scoping refers to setting the scope, or range of functionality of a variable so that it may be called  from within the block of code in which it is defined.

The scope of the variable is determined by the program's lexical structure. Variables can be declared within a specific scope and are only accessible within that region.

Simply the space where the variables are defining called as `Lexical Scope` and the variables can access in that particular scope only.

> 
The child function is lexically bound to the parent function.

`Note:` Before going to understand the Lexical Scope, you have to know what is Scope, Different type of Scopes and Scope Chain.

## SCOPE
Scope is nothing but a particular block in program. This is referred with curly brackets (`{}`). The variables can access in those particular scopes (blocks) only.

> An inner (child) scope has access to its parent (outer) scope, but an outer scope does not have access to its child scope.

## GLOBAL SCOPE

- 
When the variables are defined outside of all functions and blocks, it has a global scope. 
- 
This means that it can be accessed from anywhere within the program, including within functions. 
- 
The outermost scope in program is Global Scope. 
- 
While javascript runs in browser, windows is default global scope, because it can access from anywhere in the program.

```javascript
const firstName = 'ram'
const lastName = 'raj'
const age = 23

function userName (){
    console.log(`first name is ${firstName}`)
    function userAge (){
        console.log(`last name is ${lastName}`)
    }
    userAge()
    return
}

function userAge(){
    console.log(`age is ${age}`)
}

userName()
userAge()
console.log(`user name ${firstName} ${lastName} age is ${age}`)
```
If we observe the above code, the three variables are from global scope means they can access from anywhere in program.

## LOCAL SCOPE
When a variable is defined within a function or block, it has a local scope. This means that it can only be accessed within that function or block.
Local Scope can divide into two scopes, those are `block scope` and `function scope`.

## BLOCK SCOPE
ES6 introduced the `let` and `const` keywords, which allows variables to have block scope. This means that variables defined within a block of code (such as within an if statement or a for loop) can only be accessed within that block.

```javascript
const num = 9

if(num % 2 === 0){
    console.log(`${num} is even`)
}else{
    console.log(`${num} is odd`)
}
```
If we observe the above code, the variable `num` is in global scope, so we can access inside the if block also.

```javascript
const isOk = false

if(isOk){
    const val = 'you can continue'
    console.log(val)
}else{
    const val = 'you have to stop'
    console.log(val)
}
```
In the above code the variable `val` is in the block scope. That's why even if we declared two times, in those two blocks we are not getting any error like `SyntaxError: Identifier 'val' has already been declared`. Because that variable works inside that particular block only otherwise we can see another example.

```javascript
const isOk = false

if(isOk){
    const val = 'you can continue'
    console.log(val)
}else{
    const val = 'you have to stop'
    console.log(val)
}
console.log(val)
```
Here we can get error at last line is `ReferenceError: val is not defined` because the variable val is in block scope means that cannot access outside that particular block.

**FUNCTION SCOPE**
While introducing let and const, these variable types allows function scope. A variable is defined within the function then the variable can access only within that function.

Function scope is same as block scope but it works inside the function.

```javascript
const globalVariable  = 'hello everyone'

function main(){
    const functionVariable = 'hello function'
    console.log(functionScope)
}
console.log(globalVariable)            //hello everyone
main()                                 //hello function
console.log(functionVariable)          //ReferenceError
```
In the above code we got an error at last line is `ReferenceError: functionScope is not defined` because the variable `functionVariable` is in function scope and it is not accessible to outside of the function scope.

**NESTED SCOPE**
When a function is defined within another function, it has access to variables defined in the parent function. This is known as nested scope.

```javascript
function outerFn(){
    const outerVal = 'Hello outer function'
    function innerFn(){
        const innerVal = 'Hello inner function'
        console.log(`${outerVal} and ${innerVal}`)
    }
    innerFn()
}

outerFn()      //Hello outer function and Hello inner function
```
Here the function `innerFn` having nested scope because it can access the variables which have defined in the parent function `outerFn`.

**SCOPE CHAIN**
JavaScript uses a chain of traversed scopes to find the variables accessible in a certain scope. It will look for a referred variable in the current scope and continue on to the parent scopes until it reaches the global scope and finds the variable.

> The global scope is always the last scope of any JavaScript scope chain. In other words, the global scope is where all searches will end.

```javascript
const res = 'hello'

function outerFn(){
    function innerFn(){
        return res
    }
    return innerFn()
}

console.log(outerFn())

```
In the above code when we return the variable `res` then it's finding the value of variable inside the `innerFn` scope after it won't find then starts finding in the parent scope `outerFn`. Even it's not find then it will start finds in the global scope. Finally the value in variable `res` will be execute. This process of finding variable from child to parent scope is called Scope Chain.

`Note:` Now read the definition of Lexical Scope once again, then you will get clear idea about it.

## CONCLUSION
I hope you people understand what are Scope, Scope Chain and finally Lexical Scope. We will discuss another topic in next post.

Peace 😊