JS / 24.05.2023 / Alex

Scopes & Closures

1. What is the difference between global scope, function scope, and block scope in JavaScript?

  1. There are variables.
    1. Don't think much about scopes.
  2. Functions limit visibility of any variables.
  3. Blocks limit visibility of variables created with let and const keywords.
  4. Variables created anywhere without keywords can be accessed via window.
function lesson() {
  teacher = 'Suzy';
}
lesson();
window.teacher; // Suzy

2. Hoisting

teacher = 'Suzy';
name = teacher;
name;
// works without keywords at all

Some websites tell hoisting is when you have an access to the variable before its initialisation. The code above shows confusing example.

There is no word "hoisting" in specification!

Kyle Simpson says JavaScript has at least two phases (creation, execution) of compilation. JS makes tree of variables before code execution.

{
  console.log('start');
  console.log(variableName);
  console.log(
    'this text will not be printed, though `variableName` can be anything'
  );
  let variableName = 42;
}

Hoisting is when js knows about variables before execution.

Variables created with var keywords have undefined as a default value.

var a = 1;
function test() {
  var b = 2;
}
{
  var c = 3;
}
if (true) {
  var d = 4;
}
a; // 1
c; // 3
d; // 4
b; // ReferenceError: b is not defined

3. Closures

Problem:

function sayI() {
  // by the time of access `i` is already `3`
  console.log(i);
}
for (var i = 0; i < 3; i++) {
  setTimeout(sayI); // saves pointer to function
}

Solution:

function wrapper(i) {
  // var i = $$i
  function sayI() {
    console.log(i); // local`i` is linked to the function
  }
  setTimeout(sayI);
}
for (var i = 0; i < 3; i++) {
  wrapper(i);
}

Don’t forget how loops work!

for (var i = 0; i < 3; i++) {}
// works like:
for (var $$i = 0; $$i < 3; $$i++) {
  var i = $$i;
}

// and let
for (let i = 0; i < 3; i++) {}
// works like:
for (let $$i = 0; $$i < 3; $$i++) {
  let i = $$i;
}

4. IIFE

  • Write functions without actual storing
  • Old way to pass object and data. Container like library.

5. Shadowing

It’s just a name of variable names confusion.

var name = 'Alex';
function showName(name) {
  var name = 'Suzy';
  console.log(name);
}
showName(name);
console.log(name);