JavaScript provides different ways to define functions, including arrow functions and regular functions. Arrow functions were introduced in ES6 (ECMAScript 2015) to provide a shorter syntax for writing function expressions. Regular functions, which use the function keyword, remain important for many programming tasks.
Although both types of functions can accept parameters and return values, they behave differently, especially when handling the this keyword, constructors, and arguments.
In this tutorial, you will learn the differences between arrow functions and regular functions, how they handle this, and when to use each type.
What Is a Regular Function in JavaScript?
A regular function is a function declared using the function keyword. It can be created using a function declaration or a function expression.
Regular Function Declaration
function add(a, b) {
return a + b;
}
console.log(add(10, 20));
Output:
30
In this example, add() is a regular function that accepts two parameters and returns their sum.
Regular Function Expression
A regular function can also be assigned to a variable.
const multiply = function(a, b) {
return a * b;
};
console.log(multiply(4, 5));
Output:
20
Regular function declarations are generally hoisted, allowing them to be called before their declaration in the same scope. Function expressions follow the initialization rules of the variable used to store them.
Learn more in the JavaScript Functions tutorial.
What Is an Arrow Function in JavaScript?
An arrow function is a function expression that uses the => syntax. It provides a concise way to define functions and is commonly used for callbacks, array methods, and event handling.
Example of an Arrow Function
const add = (a, b) => {
return a + b;
};
console.log(add(10, 20));
Output:
30
For a function that returns a single expression, you can omit the curly braces and the return keyword.
const add = (a, b) => a + b;
console.log(add(10, 20));
Output:
30
The expression a + b is returned automatically because the arrow function uses an expression body.
For more examples, read the JavaScript Arrow Functions tutorial.
Arrow Functions vs Regular Functions
Arrow functions and regular functions can perform many of the same tasks, but they differ in several important ways.
| Feature | Arrow Functions | Regular Functions |
|---|---|---|
| Syntax | Uses => | Uses the function keyword |
this behavior | Inherits this from the surrounding scope | this depends on how the function is called |
Own arguments object | No | Available in ordinary non-arrow functions |
| Constructor support | Cannot be used with new | Constructible regular functions can be used with new |
| Implicit return | Supported with expression bodies | Not supported |
| Hoisting | Arrow function expressions are not hoisted like function declarations | Function declarations are hoisted |
| Common uses | Callbacks, array methods, concise functions | Function declarations, constructors, and methods requiring dynamic this |
Neither function type is always better. The right choice depends on the behavior you need.
Difference in Syntax
The most noticeable difference is how the two types of functions are written.
Regular Function
function square(number) {
return number * number;
}
console.log(square(5));
Output:
25
Arrow Function
const square = number => number * number;
console.log(square(5));
Output:
25
Both functions calculate the square of a number. The arrow function uses less syntax.
Difference in the this Keyword
The most important difference between arrow functions and regular functions is how they handle this.
A regular function gets its this value from how it is called. An arrow function does not create its own this; instead, it uses the this value from its surrounding lexical scope.
this in a Regular Function
When a regular function is called as an object method, this refers to the object before the dot.
const person = {
name: "Alex",
greet: function() {
console.log(this.name);
}
};
person.greet();
Output:
Alex
The function is called as person.greet(), so this refers to person.
this in an Arrow Function
An arrow function does not receive its own this value from the method call.
const person = {
name: "Alex",
greet: () => {
console.log(this.name);
}
};
person.greet();
In a typical browser script, this will not print "Alex". The arrow function inherits this from the surrounding scope, not from person. The exact result depends on that surrounding scope.
To create an object method that accesses the object’s properties through this, use regular method syntax.
const person = {
name: "Alex",
greet() {
console.log(this.name);
}
};
person.greet();
Output:
Alex
This distinction is essential when choosing between arrow functions and regular functions.
Arrow Functions and this
The this keyword refers to the value associated with the current function call or surrounding lexical context. Its behavior depends on how the function is defined and invoked.
Arrow functions are particularly useful when you want a nested callback to retain the surrounding this value.
Example: Regular Function Inside a Method
Consider the following example:
const person = {
name: "Alex",
greet: function() {
setTimeout(function() {
console.log(this.name);
}, 1000);
}
};
person.greet();
In this example, the callback passed to setTimeout() is a regular function. When the timer invokes it, its this is not the person object. In a typical browser environment, this.name will therefore be undefined.
Example: Arrow Function Inside a Method
You can solve this problem by using an arrow function for the callback.
const person = {
name: "Alex",
greet: function() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
person.greet();
Output after approximately one second:
Alex
The arrow function inherits this from the surrounding greet() method call, where this refers to person.
This is one of the most useful applications of arrow functions in JavaScript.
Arrow Functions Cannot Be Used as Constructors
Regular functions that are constructible can be used with the new keyword to create objects.
function Person(name) {
this.name = name;
}
const person = new Person("Alex");
console.log(person.name);
Output:
Alex
Arrow functions cannot be used as constructors.
const Person = (name) => {
this.name = name;
};
// TypeError: Person is not a constructor
const person = new Person("Alex");
If you need to create objects using constructor syntax, use a suitable regular function or a JavaScript class.
Learn more about objects in the JavaScript Objects tutorial.
Arrow Functions Do Not Have Their Own arguments Object
Regular functions have access to their own arguments object, which contains the arguments passed to the function.
function showArguments() {
console.log(arguments[0]);
console.log(arguments[1]);
}
showArguments("Apple", "Banana");
Output:
Apple
Banana
Arrow functions do not have their own arguments object. If they reference arguments, they may access it from a surrounding non-arrow function, if one exists.
To collect multiple arguments in an arrow function, use rest parameters.
const showArguments = (...items) => {
console.log(items);
};
showArguments("Apple", "Banana");
Output:
["Apple", "Banana"]
The rest parameter ...items collects the arguments into an array.
When Should You Use Arrow Functions?
Arrow functions are useful when you need a concise function expression or a callback that inherits this from its surrounding scope.
Common use cases include:
- Array methods such as
map(),filter(), andforEach(). - Callbacks passed to other functions.
- Short calculations and transformations.
- Nested callbacks that need the surrounding
thisvalue. - React event handlers and other component logic.
For example:
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(number => number * 2);
console.log(doubled);
Output:
[2, 4, 6, 8]
The arrow function transforms each number and returns the result.
Explore more examples in the JavaScript Array Methods tutorial.
When Should You Use Regular Functions?
Regular functions are useful when you need a function with its own this behavior or when creating a constructor.
Use regular functions when:
- Defining object methods that rely on their call-time
thisvalue. - Creating constructor functions that work with
new. - Using the function’s own
argumentsobject. - Writing a function declaration that should be callable before its declaration in the same scope.
For example, regular method syntax is appropriate when you want to access an object’s properties using this.
const car = {
brand: "Toyota",
displayBrand() {
return this.brand;
}
};
console.log(car.displayBrand());
Output:
Toyota
Frequently Asked Questions
What is the main difference between arrow functions and regular functions?
Arrow functions use concise syntax and inherit this from their surrounding scope. Regular functions have their own this behavior, determined by how they are called.
Can arrow functions return values?
Yes. They can return values explicitly using return inside a block body or implicitly through an expression body.
Can arrow functions be used as object methods?
Yes, but they are usually not suitable when the method needs this to refer to the object. Regular method syntax is generally preferable for that purpose.
Why do arrow functions not work with new?
Arrow functions are not constructible and do not have the internal constructor capability required by new.
Should I always use arrow functions?
No. Use arrow functions when their concise syntax and lexical this behavior fit the task. Use regular functions or method syntax when you need different this behavior or constructor support.
How do arrow functions help in React?
Arrow functions are frequently used for callbacks, event handlers, and array transformations in React applications. Understanding their behavior helps prevent common mistakes involving this and function execution.
What to Learn Next
Continue learning JavaScript functions and ES6 concepts with these tutorials: