JavaScript: Arrow Functions vs Regular Functions
Arrow functions (() => {}) were introduced in ES6 and quickly became a staple in modern JavaScript due to their concise syntax. However, they are not just syntactic sugar for regular functions.
What are the differences between an arrow function and a regular function?
Interviewers ask this to test your understanding of JavaScript's execution context, specifically how the this keyword behaves.
Here are the 4 major differences you must know.
1. The this Keyword (Lexical Scoping)
The most critical difference lies in how this is resolved.
Regular Functions
In a regular function, this is dynamic. It is determined by how the function is called at runtime.
const user = {
name: "Alice",
sayHello: function() {
console.log("Hello, " + this.name);
}
};
user.sayHello(); // "Hello, Alice" (this refers to user)
const isolatedFunction = user.sayHello;
isolatedFunction(); // "Hello, undefined" (this refers to the global object/window)Arrow Functions
Arrow functions do not have their own this. Instead, they inherit this from the lexical scope (the surrounding code where the arrow function was defined). It does not matter how or where the arrow function is called; its this is locked to its parent context.
const user = {
name: "Alice",
sayHello: () => {
// 'this' is inherited from the outer scope (e.g., window or module), NOT the user object!
console.log("Hello, " + this.name);
}
};
user.sayHello(); // "Hello, undefined"Note: This makes arrow functions perfect for callbacks (like inside setTimeout or .map()) where you want to preserve the this context of the outer class or function.
2. The arguments Object
Regular Functions
Regular functions have access to a special array-like object called arguments, which contains all the arguments passed to the function, even if they aren't explicitly defined in the parameters.
function sum() {
console.log(arguments); // [1, 2, 3]
}
sum(1, 2, 3);Arrow Functions
Arrow functions do not have their own arguments object. If you try to access it, it will look up the scope chain and find the arguments of the closest regular function, or throw an error.
const sum = () => {
// console.log(arguments); // ReferenceError: arguments is not defined
};
// Workaround: Use rest parameters instead
const modernSum = (...args) => {
console.log(args); // [1, 2, 3]
};
modernSum(1, 2, 3);3. Usage as Constructors (new keyword)
Regular Functions
Regular functions can be invoked with the new keyword to create instances of objects.
function Car(model) {
this.model = model;
}
const myCar = new Car("Toyota"); // Works perfectlyArrow Functions
Arrow functions cannot be used as constructors. They do not have a prototype property and will throw an error if invoked with new.
const Car = (model) => {
this.model = model;
};
// const myCar = new Car("Toyota"); // TypeError: Car is not a constructor4. Implicit Return
Arrow functions offer a concise syntax for implicit returns. If the function body consists of a single expression, you can omit the curly braces {} and the return keyword.
// Regular Function
const addRegular = function(a, b) {
return a + b;
};
// Arrow Function (Implicit return)
const addArrow = (a, b) => a + b;Senior-Level Interview Answer
The fundamental difference between arrow functions and regular functions is how they handle execution context. Regular functions have dynamic
thisbinding, meaningthisis determined by the invocation context at runtime. Arrow functions, conversely, lack their ownthiscontext and instead resolve it lexically from their enclosing scope, making them ideal for passing callbacks without needing to use.bind(). Additionally, arrow functions do not possess their ownargumentsobject (rest parameters should be used instead), they lack aprototypeproperty preventing them from being instantiated with thenewkeyword, and they offer syntactic sugar for implicit returns.
Common Interview Mistakes
❌ Using arrow functions as object methods
Candidates sometimes write object methods using arrow functions, expecting this to refer to the object.
const obj = {
value: 10,
getValue: () => this.value
};
console.log(obj.getValue()); // undefined!Because arrow functions inherit this from the outer scope, this does not point to obj. Always use regular functions or concise method syntax (getValue() {}) for object methods.
❌ Misunderstanding implicit object returns
When trying to implicitly return an object literal from an arrow function, candidates often forget to wrap the object in parentheses.
// Wrong: JS thinks {} is the function body block!
const getUser = () => { name: "Alice" };
// Correct: Wrap in parentheses
const getUser = () => ({ name: "Alice" }); 