Global Block Bindings

Another way in which let and const are different from var is in their global scope behavior. When var is used in the global scope, it creates a new global variable, which is a property on the global object (window in browsers). That means you can accidentally overwrite an existing global using var, such as:

  1. // in a browser
  2. var RegExp = "Hello!";
  3. console.log(window.RegExp); // "Hello!"
  4. var ncz = "Hi!";
  5. console.log(window.ncz); // "Hi!"

Even though the RegExp global is defined on window, it is not safe from being overwritten by a var declaration. This example declares a new global variable RegExp that overwrites the original. Similarly, ncz is defined as a global variable and immediately defined as a property on window. This is the way JavaScript has always worked.

If you instead use let or const in the global scope, a new binding is created in the global scope but no property is added to the global object. That also means you cannot overwrite a global variable using let or const, you can only shadow it. Here’s an example:

  1. // in a browser
  2. let RegExp = "Hello!";
  3. console.log(RegExp); // "Hello!"
  4. console.log(window.RegExp === RegExp); // false
  5. const ncz = "Hi!";
  6. console.log(ncz); // "Hi!"
  7. console.log("ncz" in window); // false

Here, a new let declaration for RegExp creates a binding that shadows the global RegExp. That means window.RegExp and RegExp are not the same, so there is no disruption to the global scope. Also, the const declaration for ncz creates a binding but does not create a property on the global object. This capability makes let and const a lot safer to use in the global scope when you don’t want to create properties on the global object.

I> You may still want to use var in the global scope if you have a code that should be available from the global object. This is most common in a browser when you want to access code across frames or windows.