I see more and more articles telling us that we should drop our old function
or var
keywords to switch to the new and better () => {}
, const
and let
. These features have many advantages and you should use them. But not as drop-in replacements.
The fat arrow function () => {}
The fat arrow function () => {}
is not equivalent to function() {}
. It is not just syntactic sugar to ease your eyes. You will break your applications with unexpected bugs if you simply replace one by the other. Mostly because the fat arrow function does not create a new context. It means that this
is the same inside and outside of the brackets : when the old function
keyword creates a new context.
Here is what is gives in action:
const myObject = {
func: function() { console.log(this) },
arrowFunc: () => { console.log(this) },
};
myObject.func();
// {func: Ę, arrowFunc: Ę}
myObject.arrowFunc();
// Window {parent: Window, opener: null...
// or any global object if you are not executing in the broswer
Sometimes you want a new context, sometimes you donāt. It depends on your use case. But if you have a sufficiently complex application, there are roughly 100% chances that it is at some point relying on the fact that a function is creating a new context. So donāt blindly āupdateā to the new syntax.
var let const
It is easy to understand that you cannot replace var
by const
everywhere. A const
should never be reassigned and you can see in your code that you reassign sometimes.
But I have read a few times that let
is a perfect drop-in replacement for var
. It is not.
let
is not hoisted
Here is the ānot hoistedā in action:
console.log(foo);
// Uncaught ReferenceError: foo is not defined
let foo = 'bar';
console.log(foo);
// undefined
var foo = 'bar';
When declaring a variable with var
, the declaration is hoisted at the top of the scope (but not the assignation, this is why it logs undefined
and not bar
). When declaring a variable with let, it is not. So if you search/replace var by let in a project, it is almost certainly breaking something.
let
is block scoped.
Here is the āblock scopedā in action:
for(let i = 0; i < 1; i++) {}
console.log(i)
// Uncaught ReferenceError: i is not defined
for(var i = 0; i < 1; i++) {}
console.log(i)
// 1
The let
has been defined in a block and is not accessible outside of that block. It can even be a simple bracket block as { let i = 1; }
. Once again, if you blindly replace all your vars by lets, you will break things.
But by all means, do it. The way let
behaves is usually better than the way var
behaves. Break your app and fix it to work with let
.
Conclusion
The old ES5 keywords are not deprecated. They do things that ES6 features cannot do. So we should keep them and use them when needed.
ES6 allow cleaner code and will force you to block scope for example. This is a good thing.