JavaScript scope in action

● First, we create a function, as before, to calculate an age

function calcAge(birthYear) {<!-- -->
  const age = 2037 - birthYear;
  return age;
}

● Then we create a global variable and call this function

const firstName = "IT knowledge";
calcAge(1998);

● Because firstName is a global variable, we can also call this variable in the function

function calcAge(birthYear) {<!-- -->
  const age = 2037 - birthYear;
  console.log(firstName);
  return age;
}

Note: The function here will first look for this variable in its own scope. If it cannot find it, it will look up the scope chain for this variable until it finds it. If it cannot find it, it will report an error!

● Now let’s add another function within the function

function calcAge(birthYear) {<!-- -->
  const age = 2037 - birthYear;

  function printAge() {<!-- -->
    const output = `You are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);
  }
  printAge();
  return age;
}

Note: The age variable is called in the printAge function, but it is not found in the function scope, so it is searched through the scope chain and then in the parent scope, and finally it is found and printed. However, the age variable can only be used internally within the entire calcAge function, not externally. This variable cannot be used

function calcAge(birthYear) {<!-- -->
  const age = 2037 - birthYear;

  function printAge() {<!-- -->
    const output = `You are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);
  }
  printAge();
  return age;
}

const firstName = 'IT knowledge';
calcAge(1998);
console.log(age);

Remember that the translation chain is single-item and can only be accessed from the inside to the outside, but the outside cannot access the inside!
● Of course, in the function, we can also add firstName because it is a global variable

 function printAge() {<!-- -->
    const output = `${<!-- -->firstName}, you are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);
  }
  printAge();
  return age;
}

● Now, we add if judgment in printAge

 function printAge() {<!-- -->
    const output = `${<!-- -->firstName}, you are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);
  }

  if(birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
    const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
    console.log(str);
  }

  printAge();
  return age;
}

Because firstName is a global variable, the if condition can still find this variable through the scope chain.

● However, the str variable cannot be accessed outside the if area.

function printAge() {<!-- -->
    const output = `${<!-- -->firstName}, you are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);
  }

  if (birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
    const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
    console.log(str);
  }
  console.log(str);

  printAge();
  return age;
}

Because let and const are block scopes, the above can take effect.
● Now we create a variable using var

 if (birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
    var millenial = true;
    const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
    console.log(str);
  }
  console.log(millenial);

Because var is not a block-level scope, but a function scope. It can be called in a function, but it cannot be called globally or without the upper-level function. This still needs to comply with the scope chain. ;
● Of course, now we create a functional function in the if, which is still a block-level area and cannot be accessed externally

 if (birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
    var millenial = true;
    const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
    console.log(str);

    function add(a, b) {<!-- -->
      return a + b;
    }
  }
  console.log(millenial);
  console.log(add(2, 3));

Note: This is only in strict mode

● But if we remove the strict mode, it will be called normally

But we use strict mode to write our code, which will reduce the number of weird situations in the code!
● What will happen if we declare the name variable in the if condition?

 if (birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
    var millenial = true;
    const firstName = "mark";
    const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
    console.log(str);

    function add(a, b) {<!-- -->
      return a + b;
    }
  }

This is more verified. It will first search in its own scope. If found, it will not search through the scope chain to the parent scope; in addition, we should not use the internal firstName and The external one is regarded as one variable. In essence, they are two variables, they just happen to have the same name.
● So what happens if we reassign the external function internally?

function calcAge(birthYear) {<!-- -->
  const age = 2037 - birthYear;

  function printAge() {<!-- -->
    let output = `${<!-- -->firstName}, you are ${<!-- -->age} years old and were born in ${<!-- -->birthYear}`;
    console.log(output);

    if (birthYear >= 1981 & amp; & amp; birthYear <= 1996) {<!-- -->
      var millenial = true;
      const firstName = 'mark';
      const str = `Wow, you're a millennial, ${<!-- -->firstName}`;
      console.log(str);

      function add(a, b) {<!-- -->
        return a + b;
      }

      output = 'NEW OUTPUT';
    }
    console.log(millenial);
    // console.log(add(2, 3));
    console.log(output);
  }
  printAge();
  return a

● But as follows

const output = 'NEW OUTPUT';

There is a difference between reassigning a variable and creating a variable!