Share it!

ES6 is a major update to JavaScript that includes dozens of new features, along with some cool new features that make programming in JavaScript more flexible and streamlined. Before ES6, functions were defined using either a “function declaration” or a “function expression”. ES6 brings the concept of “arrow functions”, providing new ways of declaring and using JavaScript functions.

Function declarations

Declared functions are not executed immediately. The code parser finds and defines all functions (function hoisting) before actually executing the script, making them available no matter where they’re declared. Function declarations may be located after the code that uses it and it will still work.

For instance, the following statement declares the function “plusOne” but no actual code is executed until the function is invoked somewhere else in the code

function plusOne(num) {
  return (num + 1);
}

Function expressions

In contrast, function expressions are JavaScript functions defined and stored in a variable (in ES6, they can also be declared in a constant):

var plusOne = function (num) {
return (num + 1);
};

Function expressions aren’t hoisted, which allows them to retain a copy of the local variables from the scope where they were defined.

JavaScript Functions defined using an expression can only be invoked only AFTER they’re defined. If invoked earlier in the code, it’ll be undefined and it will end up in an error.  After a function expression is stored in a variable, the variable is used as a function.

Functions stored in variables do not need function names (i.e.they’re defined as an anonymous function). They are always invoked (called) using the variable name. There are several different advantages in using function expressions instead of function declarations, as they can be used as:

  • Closures (an inner function with its own private variables).
  • Arguments to other functions.
  • IIFE – Immediately Invoked Function Expressions (functions executed immediately, as soon as they are created).

Arrow functions

Arrow functions (also known as “fat arrow functions”) are undoubtedly one of the more popular features of ES6. They introduced a new way of writing concise functions. As with function expressions, arrow functions must be defined before being called upon.

Arrow function syntax comes in different flavors, depending on our usage. All the variations have one thing in common, i.e they begin with the arguments, followed by the arrow (=>), followed by the function body. Here’s the most basic example:

const plusOne = num => num + 1;

The return keyword and the curly brackets can be omitted if the function takes one argument (parameter) and the function body has a single statement. However, it might be a good habit to always keep them to make code more readable (no performance issues using either format).

const plusOne = (num) => { return num + 1; }

If the function contains either no arguments or more than one, the parenthesis must be in place. For a function body having more than just a return statement, you need to wrap the body in curly braces just like traditional functions. Also, when the curly braces are present, you must always write the return statement as well.

A few comments about arrow functions:

  • They can’t be called with new, can’t be used as constructors (and therefore lack the prototype object as well).
  • No arguments object is available. You can use “rest” parameters (three dots syntax) however.
  • Arrow functions are anonymous (no name). This anonymity makes it harder to debug (the name of the function or the exact line number where the error occurred can’t be traced)
  • No self-referencing. This means that if the function needs to have a self-reference at any point (e.g. invoke itself recursively), it won’t work.

On the positive side, since JavaScript functions are first-class objects, arrow functions make writing functional code like lambda expressions and currying much easier.

Arrow functions have their own scope (have their own, private variables), but they have no ‘this’ of their own. Arrow functions don’t redefine the value of this within their function body and use the one from the context they’re defined.

This prevents many unwanted side-effects and  makes it a lot easier to predict their behavior when passed as callbacks or methods like map, reduce, or forEach. This behavior prevents bugs caused by the use of the this keyword within callbacks.


Share it!