Intro to ES6 functions

Despite ES6/ES2015 (or ES2016 now) not being officially released, it is very much in use at the moment through the use of different packages and varying levels of support in node.js and other frameworks. A quick google search for “Introduction to ES6” will net a lot of results about the upcoming functionality of ES6, a lot of it quite technical. This post is simply to reinforce at a very basic level, some of the major incoming changes.

The main contender for allowing web developers to make use of ES6 is babel.js. Babel is incredibly helpful in transforming ES6 code back into browser-supported ES5 code. The babel website also includes what is a much more detailed version of what I’m going to write here, which is their learn ES 2015 page which I would suggest reading over if you’ve got more time. One more thing to note regarding babel is that it supports JSX, the file type popularised by the React.JS framework.

This post is going to go over some of the key features included in ES6 to act as a cheatsheet if you come across some code that you don’t recognise, and to help you understand it in terms of ES5. This post will not cover every new feature coming in ES6, but those which I’ve used and I expect will see a lot of use in the future. For a full list of changes coming in ES6, take a look at the further reading section at the bottom of this post.

Arrow function expressions (or Fat Arrow function):

An arrow function expression is a shorthand version of function expressions found in ES5. If you’ve used coffeescript in the past, this will look quite familiar to you. Here is an example of the new syntax:

(param1, param2) => {
  // code

which would look like this in ES5:

function(param1, param2) {
  // code

One important difference when making use of an arrow function is that it will share the same lexical this as the environment it was called from which means in this example –

var person = {
  name: "Mike",
  favouriteNumbers: [1,2,3],
  showNumbers() {
    this.favouriteNumbers.forEach(num =>
      console.log(num +
                  " is one of " +
                  "'s favourite numbers!");

– is still accessible within the forEach arrow function as a reference to the person object’s name property.

Template Strings:

Template strings provide syntactic sugar for constructing strings. If you’re familiar with other languages, you will have seen string interpolation before which allows you to place a variable directly inside of a string between special symbols.

Previously in JavaScript, combining variables with strings could be accomplished by:

var name = "Mike";
console.log("Hello, " + name);

This method can get a bit messy when you’ve got a lot of strings and it can be a bit prone to error when you have a lot of different quotation marks to handle. The ES6 way to do this looks like:

var name = "Mike";
console.log(`Hello, ${name}`);

Notice that the entire string is contained within backticks as opposed to other type of quotations.

Although there are more use-cases for template strings, another interesting feature I found interesting is the ability to create multi-line strings like this:

`This is not
legal in ES5`

Module importing:

A feature that is very common in node.js and other languages is the ability to import code from different files into our main JavaScript files. This allows us to separate concerns to a greater extent and create reusable modules allowing us to focus on writing well-structured, decoupled code. Here is an example of this idea:

// greeting.js

export function greet(name) {
  console.log(`Hello, ${name}!`);

and then in another file:

// app.js

import { greet } from 'greeting.js';

Running the app.js file will output “Hello, Mike!”.

Import is incredibly powerful and flexible in terms of what you want to import. I may write a future post about the full extent to which import can be used in future, however if you’d like to know more now, check out the MDN page on import.

Let declarations:

Let declarations are a new way to declare a variable and in practice behave very similarly to var. The main difference is that the scope of a var variable is the entire enclosing function as illustrated in the examples below:

In a global context, these declarations are identical:

var x = 1;
let x = 1;

In a functional context, these are again identical:

function exampleFunction() {
  let x = 1;
  var x = 1;

In a block context, let is only available inside the code block that it is declared to be part of:

function exampleFunction() {
  for (let i = 0; i < 5; i++) {
    // i is only available here.

Whereas if you use var:

function exampleFunction() {
  // i is available here.
  for (var i = 0; i < 5; i++) {
    // i is available here.
  // i is available here.

Const Declarations:

A const declaration allows you to assign a value to a namespace which you are telling the program that the value will not change. One thing that can be sometimes confusing is that this does not mean the const is immutable. If you assign an object with Const, it is possible to change the properties of that object, the better way to think of const is that it can’t be reassigned to anything else. When declaring new constants, it is common practice for the name to be written in full capitals. Here are some examples to illustrate how this works:

const X = 1;
X = 10;
// this reassignment is illegal and will produce an error

Here is the object example I outlined above:

const PERSON = {
  name: "Mike"
} = "John";
// this property reassignment is legal

  name: "John"
// this reassignment is illegal because it's
// pointing the const at an entirely new value.

In practice, const is one of the clearest declarations to use throughout code. It makes the entire application a lot easier to read as you will always know what a const is referring to throughout the course of the application. For a further discussion on in practice use of var, let and const, I’d recommend Eric Elliot’s post on the matter.

EDIT: One thing I failed to mention before was that although it’s possible to make somewhat mutable objects through const. Through use of the Object.freeze({objectName}) method. Given that one of the major reasons to use a constant is to create a variable that can not be reassigned or changed, it should be considered best practice when dealing with object constants to use freeze on them. Here is how the objects should be declared:

const OBJECT = Object.freeze({
  prop: val,
  anotherProp: val2


Promises give you the ability to handle callbacks in a different way by waiting for a response from an asynchronous operation and running a block of code in a .then() block afterwards. I’ve covered Promises in more detail recently and you can read about them here:

Promises Part 1 – Asynchronous Code
Promises Part 2 – Promise Definition
Promises Part 3 – Using the Q Library

More to come:

There are a lot more new features coming in ES6 which I want to cover in more detail in their own posts, such as Generator functions and ES6 Classes (caution: more in common with typical JS Prototypal inheritance than OOP based classes). I will come back to modify this post as I create new posts about these features.

Hopefully this post has given you a basic introduction to some of the upcoming changes in ES6 and how they work. If you’ve got any specific features that you’re looking forward to in ES6, leave a comment below to let me know about it!

Further Reading:

Brief Overview of ES6 Module syntax
ES6 features – An overview and comparison of new features
Luke Hoban’s ES6 features overview
Eric Elliott on var, let and const
Official ES2015 Overview


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s