Categories
Featured Development Resources HTML/Javascript

Javascript Arrow Functions Explained

In JavaScript there are a number of ways to declare functions.  In ES6 arrow functions were added, and this article will explain their usage, and some possible pitfalls when using them.

Other Ways To Define Javascript Functions

The most familiar ways, especially if you’re looking at older code are the typical function statement:

sayHello = function() {
    console.log("Hello")
}
sayHello()
// Hello

And the function expression:

sayHello = function() {
    console.log("Hello")
}
sayHello()
// Hello

Defining Arrow Functions

This could be rewritten as an arrow function in the following manner:

sayHello = () => {
    console.log("Hello")
}
sayHello()
// Hello

Now you’re probably saying to yourself, that’s nice, but all we’re doing is not writing the word function, big deal. Are they faster or something? (and no they’re not).

They are a nice addition though and let me show you why. You can take a function and rewrite it in a single as:

sayHello => console.log("Hello")
sayHello()
// Hello

You may have heard of lambdas, or lamba functions in other programming languages, and yes this is the Javascript rendition.

They were officially made part of JavaScript with ES6, but existed earlier most famously with CoffeeScript (an older language that transpired to JavaScript that inspired many JavaScript language features that were to come).

The arrow function syntax becomes even more useful when you rewrite functions that return values in a single line:

returnHello => () => "Hello"
console.log(returnHello)
// Hello

No need for the return statement with single line arrow functions.

You can also drop the parameter brackets when having a single parameter:

helloName = name => console.log("Hello " + name)
helloName()

This concise syntax becomes very useful when using other functions that take a function as a parameter, such as the built in map function.

myArray.map(item => item.trim())

Problems With Arrow Functions

Now at this point I hope you’re clear on how arrow functions can make code more concise, but as always there are some caveats.

Returning An Object

One caveat occurs simply because of the syntax which is, if you’re simply returning an empty object with the function, you’ll need to add extra brackets in that case like this:

returnEmptyObject = () => ({});
returnEmptyObject();
// returns {}

because written like this, it can’t be determined whether the brackets are opening and closing brackets or an object:

returnEmptyObject = () => {};
returnEmptyObject();
// returns nothing

Arrow Function Scope

There is also a difference in scope when using arrow functions, they gain the scope based on where they are placed, not based on the function caller.

This becomes evident when using the this keyword, because arrow functions gain the scope based on where they were placed and not on how they are called this leads to this being undefined.

Regular functions in an object:

const object = {
    object_text: "I'm an object.",
    get_text: function() {
    return this.object_text;
    },
};
console.log(object.get_text());
// I'm an object
const object = {
    object_text: "I'm an object.",
    get_text: () => {
    return this.object_text;
    },
};
console.log(object.get_text());
// undefined

Definitely something to be aware of, and this is why you won’t see arrow functions used as object methods.

Also note, that since arrow functions gain their scope based on where they are called they have to be defined first before they are used.

No Arguments Object

Unlike regular functions arrow functions don’t have their own arguments object. Trying to access the arguments object will give an undefined

function regularFunction() {
    console.log(arguments[0])
}
regularFunction("argument")
// argument
arrowFunction = () => { console.log(arguments[0]) }
arrowFunction("argument")
// Error arguments is not defined

Conclusion

Arrow functions are a great way to shorten code. However there are caveats that a good practice not use them unless you are creating a single line function or need to use their different scope properties.