ES2015/2016
The new ecmascript standard have really changed how javascript is written. Let's list as much features as possible.
I recommend trying out the new features in a Babel repl so you can easy see how it works and what es5 code is generated when being transpiled back. Babel repl
In a lot of cases they are already supported in your browser but it's nice to get the corresponding es5 code.
let
Problem : There is only function scoping in javascript which comes as a shock to most. You expect the following to work, but it doesn't:
var a = 3;
for(var i=0; i< 3; i++) {
var a = 5;
}
console.log( a );
You expect the output to be 3
but it isn't because it is being redefined within the loop.
The keyword let
fixes this like so:
let a = 3;
for(var i=0; i< 3; i++) {
let a = 5;
}
console.log( a );
This correctly outputs 3
es5 output
var a = 3;
for (var i = 0; i < 3; i++) {
var _a = 5;
}
console.log(a);
As you can see two different variables are declared a
and _a
to handle the name collision.
lexical this
We all had that property, we never knew, or seldom knew, what this was pointing at. We solved this by writing:
function Test(){
var that = this;
var list = [1,2,3];
that.a = 3;
list.forEach(function(item){
console.log('that.a',that.a);
console.log(item);
})
}
new Test();
If we didn't create our that
variable this.a would not exist as this would refer to the inner function in forEach
.
To solve this and use a lexical this we needed to start to use an arrow function, instead of a function so instead of writing:
list.forEach(function(){})
we would instead write it as :
list.forEach(() => {})
With the full code now looking like:
function Test(){
this.a = 3;
let list = [1,2,3];
list.forEach((item) => {
console.log('this.a',this.a);
console.log(item);
})
}
new Test();
arrow functions
Let's continue to talk about arrow functions. They seem to be a neat way of not having to write the function
keyword but also ensures that lexical this becomes correct.
so basic form is this:
() => {}
and if there is only one statement happening in the arrow function you can write it like this:
list.forEach((item) => console.log(item) ) // corresponds to function(){ console.log(item); }
So far we had no parameters, but with parameters it would look like:
let odd = (i) => i % 2 != 0;
odd(3) // true
OR
let odd = i => i % 2 != 0;
odd(3) // true
I.e no parenthesis needed if only one parameter.
With more than one parameter you would need parenthesis, like so:
let max = (x,y) => x > y ? x : y
max(10,5) // 10
template string, string interpolation
This is one of my personal favourites, the ability to read properly what you are trying to concatenate.
You used to do:
var url = baseUrl + '/products/' + id
var urlWithParams = baseUrl + '/products' + '?pageSize=' + pageSize + '&page=' + page;
As you can see this is quite error prone as well as unreadable. Template strings to the rescue
let url = `${baseUrl}/products/${id}`;
let urlWithParams = `${baseUrl}/products?pageSize=${pageSize}&page=${page}`
I personally think the difference is like night and day.