DEV Community

Cover image for Introduction to JavaScript Arrow Functions
Atta
Atta

Posted on • Edited on • Originally published at attacomsian.com

39 8

Introduction to JavaScript Arrow Functions

This post was originally published on attacomsian.com/blog.


Arrow functions, introduced in ES6/ECMAScript 2015, are a syntactically compact alternative to regular ES5 functions. They are undoubtedly one of the most loved features of ES6 and are widely used nowadays. Arrow functions introduced a new way to write concise functions.

Here is a function written in ES5 function syntax:

function absolute(num) {
    return Math.abs(num);
}

absolute(-9);   //9

Now, here is the same function written using ES6 arrow function syntax:

const absolute = (num) => {
    return Math.abs(num);
}

absolute(-9);   //9

If the function body contains just a single statement, we can even omit the brackets and write everything in one line:

const absolute = (num) => Math.abs(num);

Function Parameters

If there are no parameters, just add an empty parentheses before =>:

const pi = () => Math.PI;

You can even replace empty parentheses with _:

const pi = _ => Math.PI;

If you have one ore more parameters, just pass them in the parentheses:

const abs = (num) => Math.abs(num); // on parameter
const sum = (a, b) => a + b;    // two parameters

In case of only one parameter, you can remove the parentheses completely:

const abs = num => Math.abs(num);

Concise vs Block Body

An arrow function can have either a concise body or the block body. If the function contains only a single statement, you can use a concise body. In a concise body, only the expression is specified which implicitly returns a value (without using return keyword):

const multiply = (a, b) => a * b;

In a block body, you must use an explicit return statement:

const multiply = (a, b) => {
    return a * b;
};

Look at the curly braces. They are required in a block body to wrap statements:

const oddNumber = (num) => {
    if(num % 2 == 0) {
        return false;
    } else {
        return true;
    }
};

Object Literals

If you are returning an object literal using the concise body, it must be wrapped in parentheses to avoid it being treated as a block body:

const json = () => ({x: 2}); 

this Keyword

In regular function expressions, the this keyword is bound to different value based on the context in which the function is called:

  • A new object in case of a constructor.
  • undefined in strict mode function calls.
  • The parent object if the function is called as an object method.

For example, Here is a person object which has fullName() function:

const person = {
    firstName: 'Mike',
    lastName: 'Lilly',
    fullName: function () {
        return `${this.firstName} ${this.lastName}`;
    }
};

person.fullName(); // Mike Lilly

Calling fullName() method of person object returns the full name of the person.

However, an arrow function does not have its own this and is lexically bound. It essentially means that the this scope is inherited from the code that contains the arrow function. So while looking up for this which is not present in the current scope, the ES6 arrow function will use the value of this in the scope in which it was defined. That is why the call to fullName() will not work and will return an undefined value:

const person = {
    firstName: 'Mike',
    lastName: 'Lilly',
    fullName: () => {
        return `${this.firstName} ${this.lastName}`;
    }
};

person.fullName(); // undefined undefined

Become of this arrow functions are not suited to object methods. You should also not use them as constructors either to avoid errors.

DOM Event Handling

Arrow functions can be a problem while handling events. DOM event listeners set this to be the target element. Now, if you use arrow function for callbacks, the this keyword won't be bound to the target element, but rather bound to its parent scope.

const button = document.getElementsByTagName('button')
button.addEventListener('click', () => {
  this.classList.toggle('blur');
});

Now if you click the button, you will get a TypeError because this refers to window in this scope. If you need a dynamic context for callback function, a regular function expression is required:

const button = document.getElementsByTagName('button')
button.addEventListener('click', function() {
  this.classList.toggle('blur');
});

Conclusion

Arrow functions provide a new way of writing concise functions in ES6. They are shorter, have no binding of this keyword, implicitly return a value (when the concise body is used), and are widely used in modern codebases. Arrow functions are inappropriate as object methods, and cannot be used as constructors.


✌️ I write about modern JavaScript, Node.js, Spring Boot, and all things web development. Subscribe to my newsletter to get web development tutorials & protips every week.


Like this article? Follow @attacomsian on Twitter. You can also follow me on LinkedIn and DEV.


Photo by Nick Fewings on Unsplash

A Layered Approach to Mobile App Protection

A Layered Approach to Mobile App Protection

Attackers use static analysis to understand how your app functions and the data it contains. By using multiple layers of protections like code obfuscation and string encryption, you can prevent attackers from accessing your app.

Read more

Top comments (2)

Collapse
 
umutahmet profile image
Umut Ahmet

Hey mate, nice article :)

Just a note on the this within a method in an object - there is also a shorthand way of writing a function in ES6 so this works correctly:

const person = {
    firstName: 'Mike',
    lastName: 'Lilly',
    fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
};

person.fullName(); // Mike Lilly
Collapse
 
jmergenthal profile image
Jurian Mergenthal • Edited

Good sum up, thank you :)

I would have loved to also read about arrow functions being used as class methods:

class A {
   methodA = () => {
      // do stuff...
   }

   methodB() {
      // do other stuff...
   }
}

More specifically, i think it's valuable to know, that there are differences in comparison to arrow functions outside of classes.

Short-term memory for faster AI agents

Short-term memory for faster AI agents

AI agents struggle with latency and context switching. Redis fixes it with a fast, in-memory layer for short-term context—plus native support for vectors and semi-structured data to keep real-time workflows on track.

Start building

👋 Kindness is contagious

Explore this practical breakdown on DEV’s open platform, where developers from every background come together to push boundaries. No matter your experience, your viewpoint enriches the conversation.

Dropping a simple “thank you” or question in the comments goes a long way in supporting authors—your feedback helps ideas evolve.

At DEV, shared discovery drives progress and builds lasting bonds. If this post resonated, a quick nod of appreciation can make all the difference.

Okay