1. Introduction
A function expression defines a function as part of an expression, typically by assigning it to a variable. Arrow functions, introduced in ES6, are a more concise syntax for writing function expressions. Beyond brevity, arrow functions behave differently from regular functions in several important ways, especially regarding the this keyword, the arguments object, and the prototype property.
Cricket analogy: Assigning a bowling routine to a specific player, like handing new-ball duty to a named fast bowler, is a function expression; the shorter arrow-function version is like a quick hand signal from the captain -- but it can't claim its own 'this player's stats' (this), can't reference the full bowling figures list (arguments), and can't be promoted to captain (no prototype).
2. Syntax
// function expression
const multiply = function (a, b) {
return a * b;
};
// arrow function
const add = (a, b) => a + b;
// arrow function with a block body
const square = (n) => {
return n * n;
};3. Explanation
Unlike function declarations, function expressions are not hoisted with their body — only the variable they are assigned to is hoisted (as undefined for var, or left uninitialized in the temporal dead zone for let/const). This means a function expression must be defined before it is called.
Cricket analogy: Announcing a substitute fielder's name on the team sheet before they've actually arrived at the ground is like var hoisting a function expression's variable as undefined -- you can't ask them to field (call it) until they're physically present (the assignment runs).
Arrow functions take this a step further: they have no this, arguments, or prototype of their own. Instead, they capture (inherit) the this and arguments values from the enclosing lexical scope at the time they are defined. This makes arrow functions ideal for callbacks where you want to preserve the outer this, but unsuitable as object methods that rely on their own this, and impossible to use as constructors with the new keyword.
Cricket analogy: An arrow function is like a substitute fielder who has no identity of their own on the scoreboard -- they simply borrow whichever team's colors (this) were active when they stepped onto the field, making them great as a quick relay-throw callback but useless as a named captain (object method) or as a template to train new players (constructor).
Gotcha: Because arrow functions don't have their own this, arguments, or prototype, an arrow function used as an object method will not bind this to the object — it will instead use this from whatever scope surrounds the object literal (often the global or module scope). Also, arrowFn.prototype is always undefined, so new arrowFn() throws a TypeError.
4. Example
const obj = {
name: "Timer",
start: function () {
console.log("regular:", this.name);
const arrow = () => console.log("arrow:", this.name);
arrow();
},
};
obj.start();
const arrowFn = () => {};
console.log(typeof arrowFn.prototype);5. Output
regular: Timer
arrow: Timer
undefined6. Key Takeaways
- Function expressions are not hoisted with their body; they must be defined before use.
- Arrow functions use a concise syntax and implicitly return the expression when written without braces.
- Arrow functions do not have their own this, arguments, or prototype — they inherit this lexically from the enclosing scope.
- Arrow functions cannot be used as constructors (no new keyword) and cannot be used as generator functions.
- Use arrow functions for callbacks that need the outer this; use regular functions/methods when you need dynamic this binding.
Practice what you learned
1. What does an arrow function use for its this value?
2. What happens when you try to call an arrow function with the new keyword?
3. Why does the arrow function inside obj.start() print 'Timer' instead of undefined?
4. Are function expressions hoisted the same way as function declarations?
5. Which syntax correctly implicitly returns a * b from an arrow function?
Was this page helpful?
You May Also Like
Functions in JavaScript
Learn how to declare, invoke, and understand the hoisting behavior of JavaScript functions.
The this Keyword in JavaScript
Master how the value of this is determined by how a function is called, including implicit, explicit, new, and arrow-function binding rules.
Closures in JavaScript
Understand how closures let inner functions remember and access variables from their outer scope, and how loop variable capture can trip you up.
Default and Rest Parameters in JavaScript
Use default parameter values and gather variable numbers of arguments with rest parameters.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics