/ JavaScript

Basics Of ES6 (Part 2)

Continuing from my first post, ES6 offers a vast number of new features that allows JavaScript developers to write code more intuitively using functionality that we would have to write ourselves or use a library to accomplish.

Today, we're going to be covering a few things which are as listed below:

  • Extended Parameter Handling
  • Arrow Functions
  • String Literals

Extended Parameter Handling

Unlike other languages, JavaScript always lacked the most basic of functionality when it came to passing values to functions. One of the most common examples of this is default function parameters which other languages have had for years and even decades.

With ES6, this is no more, and we now have the ability to create more robust applications without having the extra overhead that would otherwise cause our code to look and feel messy.

Default function parameters

If we look at another language such as C#, all that is needed to define a default parameter is to use a value assignment similar the expression we use when declaring a variable.

public string say(string name = "Human")
{
  return "Hello, " + name;
}

Pretty simple right? In JavaScript, it really is that simple!

function say(name = 'Human') {
  return 'Hello, ' + name;
}

If we were to call our say function without passing a string, the default value of Human would be used in its place and prevents our code from failing or even throwing exceptions unexpectedly.

Rest parameters

Rest parameters solve a very common problem that plagues at least every project that uses JavaScript, let's say we need to pass an unknown number of arguments to a function but need to store the unknown values in a single variable, in ES5 this was not possible without adding some slight overhead seen below.

function foo(a, b) {
  var c = Array.prototype.slice.call(arguments, 2);
  console.log(a, b, c);
}

foo('Bar', 'Am I b?', 'Hello', 'World');
// "Bar" "Am I b?" [ "Hello", "World" ]

In this example, we have to slice all the unknown values given to our foo function from the arguments array and assign them to a new variable which we can then use to log out the two known values followed by the remaining values.

No longer is this the case, we can now cut this code down and have it be far more intuitive without needing to make breaking changes. In ES6, we can use three periods (also known as an ellipsis) to create a rest parameter.

function foo(a, b, ...c) {
  console.log(a, b, c);
}

foo('Bar', 'Am I b?', 'Hello', 'World');
// "Bar" "Am I b?" [ "Hello", "World" ]

That's much better, not only is our code now cleaner but it is far more readable and maintainable.

Spread operators

Similar to rest parameters, we can use three periods to expand variables. Before looking at the ES6 syntax, let's first look at how we would concatenate two array's together in ES5.

var values = ['foo', 'bar'];
var merged = ['hello', 'world'].concat(values);
// [ "hello", "world", "foo", "bar" ]

And now let's see the modern syntax, drum roll...

const values = ['foo', 'bar'];
const merged = ['hello', 'world', ...values];
// [ "hello", "world", "foo", "bar" ]

Like a rest parameter, a spread operator allows us to write intuitive code. We can also apply spread operators to functions which are written in the same way with the difference that the values passed are assigned to each function parameter.

The below code example is the equivalent of using the apply method in ES5.

function log(a, b) {
  console.log(a, b);
}

log(...['foo', 'bar']);

If you've followed along this far with scratching your head, our array we're spreading out to the log function will be assigned to our function parameters separately.

Arrow Functions

One of my personal favourites when it comes to using ES6 is arrow functions which are perfect for closures inside classes and objects. To understand how they work, we first need to look at ES5 syntax.

var numbers = [2, 4, 6, 8, 10];

var doubles = numbers.map(function(num) {
  return num * 2;
});

The code above doesn't look too bad, but writing the same anonymous function over and over again would be inefficient. With ES6, we can cut our code down to just two lines.

const numbers = [2, 4, 6, 8, 10];
const doubles = numbers.map(num => num * 2);

We would receive the exact same array in our doubles variable, with the difference that we have improved it vastly and have removed the overhead of an anonymous function.

Lexical this

In JavaScript, maintaining knowledge of context can be annoying, but thankfully ES6 solves this. To understand how context in JavaScript works, let's first take a quick look at a simple constructor with a setTimeout declaration that attempts to log the name of a person.

function Person(name) {
  this.name = name;
  
  setTimeout(function() {
    console.log(this.name);
  }, 100);
}

If we run this in our browser and create a new Person instance, all we would get is a blank console output because the anonymous function declared in setTimeout refers to the window object for its context.

In ES5.1, this can be solved with the bind method.

function Person(name) {
  this.name = name;
  
  setTimeout(function() {
    console.log(this.name);
  }.bind(this), 100);
}

Much better!

With arrow functions, however, we can have the browser assign the context of this automatically without needing to use the bind method on our anonymous function.

function Person(name) {
  this.name = name;
  setTimeout(() => console.log(this.name), 100);
}

Better yet again!

It should be noted that using lexical assignments can cause unexpected behaviour, make sure you maintain an understanding of how your code flows or you can run into the same issues as the older ES5 techniques.

String Interpolation

Now let's have some real fun. One of the coolest features – in my opinion – is string interpolation. Like Swift, ES6 introduced interpolation using back-ticks, unlike Swift, which allows you just to use double quotes.

While it's a minor difference, I prefer the need for back-ticks as it defines a clear rule between static vs. dynamic. But first, let's take a look at string concatenation.

var name = 'Chris';
alert('Hello, ' + name);

Kind of ugly right? I don't mind this nor do many other developers, but it isn't the elegant solution that other languages offer. String interpolation to the rescue, when using back-ticks we can use an expression and pass our variable directly in the string rather than concatenating it.

let name = 'Chris';
alert(`Hello, ${name}`);

As you can see, we use an expression (${}) to pass our variable to which provides clarity about our strings structure. We can also declare multi-line strings with the back-ticks as shown below.

let name = 'Chris';
alert(`Hello,

${name}`);

I think it's cool, what are your thoughts?

Final Thoughts

Once again, this is still a small part of ES6. Stay tuned for more as you will continue to see just how far JavaScript has come over the recent years.

Once again, thanks for reading.

Chris Shaw

Chris Shaw

I'm a Front End Developer for Isobar Australia, I've worked on numerous projects for Dulux, ANZ, Optus and lots more.

Read More