Scopes in JavaScript

Scopes in JavaScript

  • A Scope can be defined as the current context of code execution
     
  • Scope are studied to understand where can you access a variable or function and where you can't.
     
  • Scopes are not explicitly coded, they are created based on how we have written the code, like where we have created the variables and functions, where they are initialised, and where they are being used/called. This is also called "Lexical" scope.
     
  • The lexical scope (or just scope) of a variable is the region of a program where a variable is accessible.
     
  • "Lexical" means how the code is written
const globalVar = 100_000

function func() { // (A)
  const alpha = 10;
  if (true) { // (B)
    const beta = 20;
  } else {
    console.log({beta, alpha})
    const charlie = 30
  }
}

Scopes in JavaScript

There are basically 4 types of scopes possible in Javascript:

  1. Function Scope
  2. Block Scope
  3. Module Scope
  4. Global Scope

Scopes in JavaScript

Function Scope:

  • All the types of functions (declaration, expression, methods, IIFE, arrow functions) create their own scope.
  • Any variable which is declared inside a function (using var, const or let) is not accessible outside the function.
const globalVar = 100_000

function func() { // (A)
  const alpha = 10;
  if (true) { // (B)
    const beta = 20;
  } else {
    console.log({beta, alpha})
    const charlie = 30
  }
}

console.log(alpha) // undefined

var common = 300;
function newFunc(){
  var common = 200;
  console.log({common})
}

console.log({common})
newFunc()
console.log({common})

Scopes in JavaScript

Block Scope ({}):

  • A block ({}) "curly brackets" also create a scope.
  • This scope is respected by any variable created using const or let.
  • Variables created using var do NOT respect block scope.
  • When a function is created, curly brackets are used, but it still gets a function scope not block scope
function func() { // (A)
  const alpha = 10;
  if (true) { // (B)
    const beta = 20;
  } else {
    console.log({beta, alpha})
    const charlie = 30
  }
}

for (const num of [1,2,3,4]) {
//   a block
}

if (condition) {
  // a block
} else {
  // another block
}

switch(name) {
  // a block
  case "yash":
    console.log(name)
    break;
}

Scopes in JavaScript

Creating private variables:

 

  • Before the introduction of block scopes ({}), whenever there was the need to create a private variable which cannot be accessed or modified by other code, developers had to wrap the variable inside a function.
  • But now we can isolate variables using blocks as well.
function func(){
  var isolatedVar = 100
}
console.log(isolatedVar) // undefined
isolatedVar = 300; // 'isolatedVar' is not defined

{
  const blockConstant = 200;
  let blockLet = 400;
}

console.log(blockConstant) // undefined
blockLet = 600; // 'blockLet' is not defined

Scopes in JavaScript

Global Scope (ES6):

  • In browsers, "window" object defines the global scope (a browser tab)
  • each tab in the browser has a window object of it's own
  • variables created in a ".js" file with var directly at the file's global level, get assigned in the window object or the global scope

index.html

index.js

index.css

global - (window)

Scopes in JavaScript

variables declared using "var" gets added to the global object:

  • - create 2 ".js" files, add them to HTML file using <script> tags
  • - create a variable "someVar" using "var" in one of the ".js" files
  • - open console and try "globalThis.someVar" this should give a value
  • - now change the declaration for someVar from "var" to "const"
  • - open console and try "globalThis.someVar" this should now be giving undefined.
// fileA.js

var someVar = 100

const nextVar = 500
// fileB.js

console.log(someVar) // 100
console.log(nextVar) // undefined

window.someVar // 100
window.nextVar // undefined
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
  
    <script src="fileA.js"></script>
    <script src="fileB.js"></script>
  
</head>
<body>
    <div>Hello World</div>
</body>
</html>

Scopes in JavaScript

Module Scope (ES6):

  • Modules are simply JavaScript files (.js), treated differently
    (loaded differently, read differently, import/exported differently),
  • To change a file to module - add type="module"
  • <script type="module"> tag,
  • modules also create a scope of their own
  • There are several architectures regarding modules like: CommonJS, AMD (Asynchronous Module Definition),
  • These scopes are basically for exporting and importing variables among files/modules
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
  
    <script type="module" src="fileA.js"></script>
  
</head>
<body>
    <div>Hello World</div>
    <script type="module" src="fileB.js"></script>
</body>
</html>

Scopes in JavaScript

  • - with "var" declaration, add attribute type="module" to each of the script tags,
  • now also try "globalThis.someVar"
  • should be giving undefined - because inside a "module" we're never in the global scope.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
  
    <script src="fileA.js" type="module"></script>
    <script src="fileB.js" type="module"></script>
  
</head>
<body>
    <div>Hello World</div>
</body>
</html>
// fileA.js
var newVariable = 100
const nextVar = 500
// fileB.js

console.log(newVariable) // undefined
console.log(nextVar) // undefined

window.newVariable // undefined
window.nextVar // undefined

Scopes in JavaScript

Global Objects:

 

  • window - browsers
  • global - Node.Js
  • globalThis - used to refer to global object of the environment

index.html

index.js

index.css

global - (window)

Scopes in JavaScript

  • "Duplicates" describes if a declaration can be used twice with the same name (per scope).
  • "Global prop." describes if a declaration adds a property to the global object, when it is executed in the global scope of a script (not module).
  • TDZ means temporal dead zone - the time between entering the scope of a variable and executing its declaration - temporal: time based.
  • (*) Function declarations are normally block-scoped