Academic Block

JavaScript Arrow Functions Get Certified

Arrow functions, introduced in ES6, offer a shorter syntax for writing function expressions. They are especially popular for short callbacks, but they also behave differently from regular functions in a few important ways.

In this lesson, you will learn the arrow function syntax, how implicit returns work, and how arrow functions handle this differently from regular functions.

Basic Arrow Function Syntax

An arrow function replaces the function keyword with an arrow (=>) placed after the parameter list.

What this code does: An arrow function is a shorter way to write a function expression. sayHi is defined with => and no parameters. Calling it prints the greeting.

const sayHi = () => {
    console.log("Hi there!");
};
sayHi();

Arrow Functions With Parameters

Parameters are written inside parentheses, just like regular functions.

What this code does: Arrow functions can take parameters and use a full body with curly braces and return. multiply multiplies its two arguments and returns the result, which is then printed.

const multiply = (a, b) => {
    return a * b;
};
console.log(multiply(4, 7));

Implicit Return

If the function body is a single expression, you can omit the curly braces and the return keyword. The result of the expression is returned automatically.

What this code does: With a single expression, you can omit curly braces and return (implicit return). (a, b) => a * b multiplies the values and returns the product in one short line.

const multiply = (a, b) => a * b;
console.log(multiply(6, 3));

This shorthand only works when the function body is a single expression. If you use curly braces, you must use return explicitly.

Parentheses With a Single Parameter

When an arrow function has exactly one parameter, the parentheses around it are optional.

What this code does: A single parameter can drop the parentheses around its name. celsius => ... converts 20°C to Fahrenheit and prints the result.

const celsiusToFahrenheit = celsius => (celsius * 9 / 5) + 32;
console.log(celsiusToFahrenheit(20));

Parentheses are always required when there are zero parameters, or two or more parameters.

Arrow Functions With No Parameters

What this code does: An arrow function with no parameters still needs empty parentheses (). This one returns a random integer from 0 to 99 each time it is called.

const getRandomNumber = () => Math.floor(Math.random() * 100);
console.log(getRandomNumber());

Returning an Object Literal

Returning an object literal with implicit return requires wrapping it in parentheses, since curly braces would otherwise be interpreted as the function body.

What this code does: To return an object with implicit return, wrap the object in parentheses. Without them, curly braces would be treated as a function body. The returned user object is printed.

const createUser = (username, role) => ({ username: username, role: role });
console.log(createUser("michael_dev", "admin"));

Arrow Functions as Callbacks

Arrow functions are widely used as short, inline callbacks for array methods.

What this code does: Arrow functions shine as short callbacks for array methods. map adds tax to each price; filter keeps only prices above 20. Both results are printed.

const prices = [19.99, 45.5, 8.25, 120];
const withTax = prices.map(price => price * 1.08);
console.log(withTax);
const expensiveItems = prices.filter(price => price > 20);
console.log(expensiveItems);

Arrow Functions Do Not Have Their Own this

One of the biggest differences between arrow functions and regular functions is how they handle this. An arrow function does not create its own this — instead, it uses this from the surrounding (enclosing) scope.

What this code does: Arrow functions do not have their own this; they inherit it from the surrounding scope. Inside start, the arrow callback can still update this.seconds on the timer object. (The interval is commented out so it does not run forever in the sandbox.)

const timer = {
    seconds: 0,
    start: function () {
        setInterval(() => {
            this.seconds++;
            console.log(this.seconds);
        }, 1000);
    }
};
// timer.start(); // Uncomment to see it count up in a real browser.
console.log("Arrow functions inherit 'this' from their surrounding scope.");

If a regular function were used instead of an arrow function inside setInterval, this would no longer refer to timer, and this.seconds would not work as expected.

When Not to Use Arrow Functions

Because arrow functions don’t have their own this, they generally shouldn’t be used as object methods that rely on this to refer to the object itself.

What this code does: Using an arrow function as an object method is usually wrong when you need this. Here this is not the car object, so this.brand is undefined. Prefer a regular function for methods.

const car = {
    brand: "Toyota",
    describe: () => {
        console.log(this);
        return "Brand: " + this.brand;
    }
};
console.log(car.describe());

Since describe is an arrow function, this does not refer to car, so this.brand is undefined instead of "Toyota".

Arrow Functions Don’t Have Their Own arguments Object

Regular functions have access to a built-in arguments object containing all passed arguments. Arrow functions do not have their own arguments object; using rest parameters is the modern alternative.

What this code does: Arrow functions have no arguments object. Use rest parameters instead. ...numbers collects all arguments into an array, which is then summed with reduce.

const sumAll = (...numbers) => {
    return numbers.reduce((total, current) => total + current, 0);
};
console.log(sumAll(1, 2, 3, 4));

Arrow Functions vs. Regular Functions

Aspect Regular Function Arrow Function
Syntax length Longer Shorter, supports implicit return
Own this binding Yes No (inherits from enclosing scope)
Own arguments object Yes No (use rest parameters instead)
Can be used as a constructor Yes (with new) No
Good for object methods using this Yes Generally no

Practical Example

Let’s use arrow functions to process a small list of employee records.

What this code does: A practical chain: filter employees who worked more than 40 hours, then map to their names only. Arrow functions keep each step short and readable.

const employees = [
    { name: "Sofia", hoursWorked: 42 },
    { name: "James", hoursWorked: 38 },
    { name: "Lena", hoursWorked: 45 }
];
const overtimeEmployees = employees
    .filter(employee => employee.hoursWorked > 40)
    .map(employee => employee.name);
console.log("Worked overtime:", overtimeEmployees);

Common Mistakes With Arrow Functions

  • Using an arrow function as an object method when the method needs to access this.
  • Forgetting to wrap an implicitly returned object literal in parentheses, causing the curly braces to be parsed as a function body instead.
  • Assuming arrow functions have their own arguments object.
  • Trying to use an arrow function as a constructor with the new keyword, which throws a TypeError.
  • Overcomplicating a multi-step function body by forcing it into a single implicit-return expression instead of using curly braces and return.

Best Practices for Arrow Functions

  • Use arrow functions for short, simple callbacks, especially with array methods like map(), filter(), and reduce().
  • Avoid arrow functions for object methods that rely on this.
  • Use implicit return only when it keeps the code readable; switch to curly braces and return for anything more than a simple expression.
  • Use rest parameters (...args) instead of relying on the arguments object.
  • Keep parameter parentheses consistent across your codebase, even for single parameters, for readability.

Quick Summary

  • Arrow functions use => instead of the function keyword.
  • A single-expression body can omit curly braces and return (implicit return).
  • Returning an object literal implicitly requires wrapping it in parentheses.
  • Arrow functions inherit this from their surrounding scope instead of having their own.
  • Arrow functions don’t have their own arguments object and cannot be used as constructors.
  • They are best suited for short callbacks, not object methods that depend on this.

Try It Yourself

Modify the arrow function below. Try changing the calculation, or converting it between implicit return and an explicit return statement with curly braces.

What this code does: Practice example: change the conversion factor or switch between implicit and explicit return, then click Test My Code to see the new array of kilometers.

const distances = [5, 12, 3, 8];
const kilometers = distances.map(miles => miles * 1.60934);
console.log(kilometers);
Tip: A quick way to decide between an arrow function and a regular function: if you find yourself reaching for this to refer to the object the function belongs to, use a regular function instead.

Understanding arrow functions is essential before moving on to closures, the this keyword in depth, and more advanced JavaScript concepts.

🧪 Test Your JavaScript Code

Edit the code on the left and click “Run Code” to see the console output on the right.

📝 JavaScript Code
👁 Console Output

Click “Run Code” to see the output here.

Ctrl + Enter to run code Esc to close