Obsessed with React and teaching. I help people become Frontend Developers. Living with my fiancee and Yorkshire Terrier 🐶 in Poland.
Before the advent of ES6, there were only two ways to declare variables - global variables or using
varkeyword (function or global scope).
constkeywords were introduced. Both can either have a global or block scope.
letcan be updated, but not redeclared.
constas the name implies, can't either be updated or redeclared.
Let's learn the details about each of the above keywords by looking at the code examples. After that, we'll sum up recommendations and best practices.
Globals are evil.
In the above example, we declared the
setTimeoutvariable without using any keyword and assigned the
Hello Worldstring to it. This way, the variable became global. Additionally, we accidentally overwrote the existing
setTimeoutfunction and it'll cause unwanted behavior.
The window object has a lot of built-in properties that shouldn't be overridden. Unless you have a good reason (e.g. polyfill, custom implementation), you should strive away from overriding existing variables, functions in the
In the later sections, I'll explain how to avoid global variables overrides, for now, try to study
windowobject and make sure you don't come up with the exact same name when naming your variables.
varhas the same problems as global variables, but it can be used in a function scope to not pollute the global one.
It's good that we didn't overwrite the outer
messagevariable inside of the
hellofunction as the inner
messagevariable had a function scope which is helpful in avoiding leaking of the variables to outer scopes. However, the outer
messagevariable still polluted the global scope.
Another bad thing about using
varis that it can be redeclared and updated which breaks the immutability approach of functional, declarative programming:
We redeclared and updated
canBeChangedAndUpdatedvariable 3 times and it was applied to the global scope.
varalso can't handle properly. 🙈 It means that variable declarations are moved all the way to the top of the global scope or function scope. Let's see how that works.
Only the declaration of
xwas hoisted as it printed
undefined. The best practice is to always include variable declarations and assigning values to them (in most scenarios) at the top as using hoisting is confusing and difficult to reason about. It should look like below.
We got 5 when printing it through
console.logwhich is good.
yvariable throws an error as it never was defined.
varkeyword gives too much "flexibility" and doesn't have strict rules. I don't use it anymore and couldn't be happier.
Let's see what improvements ES6 keywords bring to us.
The first improvement is that
letdoesn't add to the
windowobject when declared as a global variable. However, it's still polluting the global scope if used like below.
The second improvement is a block scope of
let. Let's see it in action.
namevariable polluted global scope but inner (inside
ifstatement) lived only there. Block scope is helpful in avoiding leaking of variables to outer scopes similar to function scope.
The third improvement is that
letcan't be redeclared, let's see what happens if we try to do that.
We get an error that notifies us
canOnlyBeUpdatedvariable can't be redeclared.
It can still be updated which contradicts the immutability concept.
And if it comes to hoisting,
letdeals with it in a bit more strict way than
Hoisting still occurs but
letlands in Temporal Dead Zone thus it's not accessible and we get an error.
xshould be declared and assigned (in most cases) before it's used.
Let's jump to the perfect one (almost) which is a
The great thing about
constis that it has all the good properties from
let- block scoped, can't be redeclared and additionally, it can't be updated. 😍
constkeyword perfectly fits in functional, declarative programming with immutability in mind.
But the almost mentioned before.
Whoops, we updated the property of the
An additional example of how good it feels to write code using
constcan be found below.
Avoiding global scope
The simplest solution is to use a function or block scope. If you need something more organized, create a namespace to avoid name collisions.
This way, the built-in
window.setTimeoutis untouched and we can declare our variables in the namespace.
Let's dive into the summary of recommendation & best practices.
You probably guessed my preference about
constbut honestly, as Dan Abramov said in his post, "I don't care". It's all about conventions agreed with the entire team. Make sure it fits all of you and set linters appropriately.
Below you can find my recommendations:
- Aim for const in most cases and block scope, minimize let to the bare minimum, don't use var.
- Strive away from global scope pollution, use e.g. webpack in your projects.
- Stick to semantic, functional programming with immutability in mind, free of side effects, not redeclaring, and updating existing variables.
I hope it was something and you could've learned a ton from the article. We went through an explanation of hoisting, scopes, and variable keywords. Additionally, you've acknowledged best practices and proposed solutions to avoid global scope pollution.
Big thanks for reading the article, you're awesome! 🙇♂️
You can also find me on:
Thanks for all the support. ❤️
THE GUIDE TO BEAT FRONTEND INTERVIEW
Let's build a community that will help each other.