tl;dr: No! Arrow functions and function declarations / expressions are not equivalent and cannot be replaced blindly.
If the function you want to replace does not use this, arguments and is not called with new, then yes.


As so often: it depends. Arrow functions have different behavior than function declarations / expressions, so let's have a look at the differences first:

1. Lexical this and arguments

Arrow functions don't have their own this or arguments binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function, this and arguments refer to the values of this and arguments in the environment the arrow function is defined in (i.e. "outside" the arrow function):

// Example using a function expression
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: function() {
      console.log('Inside `bar`:', this.foo);
    },
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: () => console.log('Inside `bar`:', this.foo),
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

In the function expression case, this refers to the object that was created inside the createObject. In the arrow function case, this refers to this of createObject itself.

This makes arrow functions useful if you need to access the this of the current environment:

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

Note that this also means that is not possible to set an arrow function's this with .bind or .call.

If you are not very familiar with this, consider reading

  • MDN - this
  • YDKJS - this & Object prototypes

2. Arrow functions cannot be called with new

ES2015 distinguishes between functions that are callable and functions that are constructable. If a function is constructable, it can be called with new, i.e. new User(). If a function is callable, it can be called without new (i.e. normal function call).

Functions created through function declarations / expressions are both constructable and callable.
Arrow functions (and methods) are only callable. class constructors are only constructable.

If you are trying to call a non-callable function or to construct a non-constructable function, you will get a runtime error.


Knowing this, we can state the following.

Replaceable:

  • Functions that don't use this or arguments.
  • Functions that are used with .bind(this)

Not replaceable:

  • Constructor functions
  • Function / methods added to a prototype (because they usually use this)
  • Variadic functions (if they use arguments (see below))
  • Generator functions, which require the function* notation

Lets have a closer look at this using your examples:

Constructor function

This won't work because arrow functions cannot be called with new. Keep using a function declaration / expression or use class.

Prototype methods

Most likely not, because prototype methods usually use this to access the instance. If they don't use this, then you can replace it. However, if you primarily care for concise syntax, use class with its concise method syntax:

class User {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

Object methods

Similarly for methods in an object literal. If the method wants to reference the object itself via this, keep using function expressions, or use the new method syntax:

const obj = {
  getName() {
    // ...
  },
};

Callbacks

It depends. You should definitely replace it if you are aliasing the outer this or are using .bind(this):

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

But: If the code which calls the callback explicitly sets this to a specific value, as is often the case with event handlers, especially with jQuery, and the callback uses this (or arguments), you cannot use an arrow function!

Variadic functions

Since arrow functions don't have their own arguments, you cannot simply replace them with an arrow function. However, ES2015 introduces an alternative to using arguments: the rest parameter.

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};

Related question:

  • When should I use arrow functions in ECMAScript 6?
  • Do ES6 arrow functions have their own arguments or not?
  • What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?
  • How to use arrow functions (public class fields) as class methods?

Further resources:

  • MDN - Arrow functions
  • YDKJS - Arrow functions
Answer from Felix Kling on Stack Overflow
🌐
Medium
mayanovarini.medium.com › functions-in-javascript-declaration-expression-arrow-d6f907dc850a
Functions in Javascript (Declaration, Expression, Arrow) | by RM | Medium
November 24, 2021 - There are three common ways of using functions and each has its own name — “Function Declaration” and “Function Expression”. There is also “Arrow Function”, which has the shortest syntax.
🌐
freeCodeCamp
freecodecamp.org › news › function-declaration-vs-function-expression
Function Declaration vs Function Expression
April 26, 2023 - The same error would occur if it were an arrow function. Therefore, only declared functions can be used before initialization. With declared functions, you already have the name: function name....
People also ask

Is it possible to convert an arrow function to a regular function?
Yes, an arrow function can be converted to a regular function declaration or function expression. Simply replace the arrow (=>) with the function keyword and include the function body within curly braces.
🌐
steveayo.com
steveayo.com › home › blog › programming › function declaration vs. function expression vs. arrow function
Function Declaration vs. Function Expression vs. Arrow Function ...
Are arrow functions always preferable over function expressions?
Not necessarily. While arrow functions provide a concise syntax, they may not always be the best choice. Function expressions offer more flexibility and are better suited for certain scenarios, such as when you need to access the arguments object.
🌐
steveayo.com
steveayo.com › home › blog › programming › function declaration vs. function expression vs. arrow function
Function Declaration vs. Function Expression vs. Arrow Function ...
Can arrow functions be used as methods in objects?
Yes, arrow functions can be used as methods in objects. However, keep in mind that arrow functions do not bind their own this value, so the this context inside an arrow function will be inherited from the surrounding scope.
🌐
steveayo.com
steveayo.com › home › blog › programming › function declaration vs. function expression vs. arrow function
Function Declaration vs. Function Expression vs. Arrow Function ...
Top answer
1 of 3
1142

tl;dr: No! Arrow functions and function declarations / expressions are not equivalent and cannot be replaced blindly.
If the function you want to replace does not use this, arguments and is not called with new, then yes.


As so often: it depends. Arrow functions have different behavior than function declarations / expressions, so let's have a look at the differences first:

1. Lexical this and arguments

Arrow functions don't have their own this or arguments binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function, this and arguments refer to the values of this and arguments in the environment the arrow function is defined in (i.e. "outside" the arrow function):

// Example using a function expression
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: function() {
      console.log('Inside `bar`:', this.foo);
    },
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: () => console.log('Inside `bar`:', this.foo),
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

In the function expression case, this refers to the object that was created inside the createObject. In the arrow function case, this refers to this of createObject itself.

This makes arrow functions useful if you need to access the this of the current environment:

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

Note that this also means that is not possible to set an arrow function's this with .bind or .call.

If you are not very familiar with this, consider reading

  • MDN - this
  • YDKJS - this & Object prototypes

2. Arrow functions cannot be called with new

ES2015 distinguishes between functions that are callable and functions that are constructable. If a function is constructable, it can be called with new, i.e. new User(). If a function is callable, it can be called without new (i.e. normal function call).

Functions created through function declarations / expressions are both constructable and callable.
Arrow functions (and methods) are only callable. class constructors are only constructable.

If you are trying to call a non-callable function or to construct a non-constructable function, you will get a runtime error.


Knowing this, we can state the following.

Replaceable:

  • Functions that don't use this or arguments.
  • Functions that are used with .bind(this)

Not replaceable:

  • Constructor functions
  • Function / methods added to a prototype (because they usually use this)
  • Variadic functions (if they use arguments (see below))
  • Generator functions, which require the function* notation

Lets have a closer look at this using your examples:

Constructor function

This won't work because arrow functions cannot be called with new. Keep using a function declaration / expression or use class.

Prototype methods

Most likely not, because prototype methods usually use this to access the instance. If they don't use this, then you can replace it. However, if you primarily care for concise syntax, use class with its concise method syntax:

class User {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

Object methods

Similarly for methods in an object literal. If the method wants to reference the object itself via this, keep using function expressions, or use the new method syntax:

const obj = {
  getName() {
    // ...
  },
};

Callbacks

It depends. You should definitely replace it if you are aliasing the outer this or are using .bind(this):

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

But: If the code which calls the callback explicitly sets this to a specific value, as is often the case with event handlers, especially with jQuery, and the callback uses this (or arguments), you cannot use an arrow function!

Variadic functions

Since arrow functions don't have their own arguments, you cannot simply replace them with an arrow function. However, ES2015 introduces an alternative to using arguments: the rest parameter.

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};

Related question:

  • When should I use arrow functions in ECMAScript 6?
  • Do ES6 arrow functions have their own arguments or not?
  • What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?
  • How to use arrow functions (public class fields) as class methods?

Further resources:

  • MDN - Arrow functions
  • YDKJS - Arrow functions
2 of 3
53

Arrow functions => best ES6 feature so far. They are a tremendously powerful addition to ES6, that I use constantly.

Wait, you can't use arrow function everywhere in your code, its not going to work in all cases like this where arrow functions are not usable. Without a doubt, the arrow function is a great addition it brings code simplicity.

But you can’t use an arrow function when a dynamic context is required: defining methods, create objects with constructors, get the target from this when handling events.

Arrow functions should NOT be used because:

  1. They do not have this

    It uses “lexical scoping” to figure out what the value of “this” should be. In simple word lexical scoping it uses “this” from the inside the function’s body.

  2. They do not have arguments

    Arrow functions don’t have an arguments object. But the same functionality can be achieved using rest parameters.

let sum = (...args) => args.reduce((x, y) => x + y, 0);
sum(3, 3, 1) // output: 7
  1. They cannot be used with new

    Arrow functions can't be constructors because they do not have a prototype property.

When to use arrow function and when not:

  1. Don't use to add function as a property in object literal because we can not access this.
  2. Function expressions are best for object methods. Arrow functions are best for callbacks or methods like map, reduce, or forEach.
  3. Use function declarations for functions you’d call by name (because they’re hoisted).
  4. Use arrow functions for callbacks (because they tend to be terser).
🌐
Reddit
reddit.com › r/learnjavascript › function declaration vs expression
r/learnjavascript on Reddit: Function Declaration vs Expression
October 21, 2023 -

So I understand the difference between the two, but is it a case where I should've use a certain one instead of the other ? Or could I just use function expression for everything?

Top answer
1 of 5
5
You need function declarations if you want to follow the pattern where you put helper functions at the end of a file but call them earlier in the file. That’s sort of an antiquated non-JS pattern at this point though. Lately, I have gravitated towards declarations for top-level functions, but arrow expressions for in-line callbacks and such. It’s all just style choices though.
2 of 5
2
Any time you use a function as you would a variable, e.g. assigning it to another variable, passing it as a callback, returning it from a parent function, using the IIFE pattern, these are all function expressions. The only time it's a function declaration is when you begin a statement with the function keyword. Function expressions: setTimeout(function () {}); (function () {})(); const f = function () {}; Function declaration: function f() {} There are a couple of minor differences: assigning a function to a const means it can't be redeclared later, so it can act as a safeguard in that context. This has never been a problem for me in the real world, however. The one big difference is that you can't use an arrow function as a function declaration, only as a function expression. My personal opinion is that, unless you have good reason to deviate, if you're simply... well... declaring a function, use a function declaration. For me, seeing the function keyword at the start of the line makes it clear that you're simply defining a function and not trying to do anything else with it, like immediately invoking it. Many people seem to prefer using const f = ..., presumably because it allows them to use arrow notation, and some people really like arrow notation.
🌐
YouTube
youtube.com › watch
ARROW FUNCTIONS vs FUNCTION EXPRESSIONS vs FUNCTION DECLARATIONS (BYTE CODE)| Advanced JavaScript - YouTube
This video is a full deep dive into Function Declarations, Function Expressions and Arrow Functions work both at a usage level and underneath the hood at a b...
Published   August 9, 2021
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › function
function expression - JavaScript - MDN Web Docs - Mozilla
The function keyword can be used to define a function inside an expression. You can also define functions using the function declaration or the arrow syntax.
Find elsewhere
🌐
DEV Community
dev.to › jessalejo › arrow-functions-vs-function-declarations-in-javascript-ael
Arrow Functions vs Function Declarations in JavaScript - DEV Community
February 3, 2025 - Arrow functions are slick and short, especially for simple stuff. No need for return if it's a one-liner. Function declarations are a little bulkier but sometimes clearer, especially for bigger functions.
🌐
freeCodeCamp
freecodecamp.org › news › the-difference-between-arrow-functions-and-normal-functions
Arrow Functions vs Regular Functions in JavaScript – What's the Difference?
April 13, 2023 - Normal functions can be declared when you use the function keyword and a name, but arrow functions cannot be declared. They can only be expressed because they are anonymous:
🌐
SteveAyo
steveayo.com › home › blog › programming › function declaration vs. function expression vs. arrow function
Function Declaration vs. Function Expression vs. Arrow Function | SteveAyo
July 4, 2023 - Function Declaration: Use function declarations when you need hoisting and want the function to be accessible throughout the code. They are suitable for defining reusable and standalone functions.
Price   $$$
Address   Tanzania
🌐
Medium
medium.com › @hnegash.n › function-declaration-vs-function-expression-vs-arrow-function-12296e6541e7
Function Declaration vs. Function Expression vs. Arrow Function | by Hanna Negash | Medium
November 11, 2023 - The symbol of an arrow is a shorthand ... The arrow function is similar to the function expression, but instead, I remove the function keyword and move the symbol => to the right side of the parentheses before the braces...
🌐
Codefinity
codefinity.com › blog › Functions-in-JavaScript
Functions in JavaScript
They are often used for inline functions or with array methods like map, filter, and reduce. Syntax: Function Declarations and Function Expressions use the function keyword, while Arrow Functions use the arrow (=>) syntax.
🌐
Jrsinclair
jrsinclair.com › articles › 2025 › whats-the-difference-between-named-functions-and-arrow-functions
What’s the difference between ordinary functions and arrow functions in JavaScript?
And then we follow with the implementation details later. Ordinarily, we can’t use a function expression or an arrow function before it’s defined. But with function declarations, we have more flexibility.
🌐
Medium
zmjdev.medium.com › function-declaration-vs-function-expression-vs-arrow-functions-right-tool-for-the-right-job-9eb23893bec1
Function Declaration vs Function Expression vs Arrow Function — Right Tool for the Right Job | by zmjdev | Medium
January 6, 2022 - ... Here, bar is inside its own ... and when we run the program we still get [Function:bar]. ... Function Expressions are the best way to self-reference....
🌐
Dmitri Pavlutin
dmitripavlutin.com › differences-between-arrow-and-regular-functions
5 Differences Between Arrow and Regular Functions
March 21, 2023 - The function declaration and function expression I'm going to reference as regular function. The second way, available starting ES2015, is the arrow function syntax:
🌐
GeeksforGeeks
geeksforgeeks.org › difference-between-regular-functions-and-arrow-functions
Difference between Regular functions and Arrow functions | GeeksforGeeks
September 11, 2024 - Regular functions offer traditional syntax and this context handling, while arrow functions provide a concise syntax and lexical this binding, making them ideal for callbacks and simpler expressions.
🌐
Go Make Things
gomakethings.com › function-expressions-vs.-function-declarations-revisisted
Function expressions vs. function declarations revisisted | Go Make Things
October 12, 2021 - The first example, function add () {}, is called a function declaration. The second example, let add = function () {}, is called a function expression. They more-or-less do the same thing, but there’s one subtle yet important difference between them. (There’s now a third way: ES6 arrow functions.
🌐
DEV Community
dev.to › ernanej › a-diferenca-entre-funcoes-tradicionais-e-arrow-functions-no-javascript-7e3
The difference between traditional functions and arrow functions in javascript - DEV Community
May 21, 2023 - Unlike the traditional declaration, arrow functions do not have their own this element, as the value of this inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of this in the closest ...
🌐
Sololearn
sololearn.com › en › Discuss › 1225057 › 4-ways-to-declare-functions-in-javascript-which-one-to-use
4 ways to declare functions in JavaScript, which one to use? | Sololearn: Learn to code for FREE!
1) Function Declaration function square(x) { return x * x; } 2) Function Expression const square = function (x) { return x * x; } 3) Arrow Function Expression const square = (x) => { return x * x; } 4) Concise Arrow Function Expression const ...