Arrow functions are a concise syntax for defining functions using the => syntax, rather than the traditional function keyword. They offer several advantages, such as more concise syntax and different behavior for this.
let func = (arg1, arg2, ..., argN) => expression;This defines a function func that takes parameters arg1, arg2, ..., argN, and evaluates the given expression.
Regular Function Expression:
jslet func = function(arg1, arg2, ..., argN) { return expression; };Arrow Function:
jslet func = (arg1, arg2, ..., argN) => expression;
Examples of Arrow Functions
Basic Arrow Functions
- Simple return (no block):js
let sum = (a, b) => a + b; // Single expression, returns result automatically let double = n => n * 2; // Single parameter, no need for parentheses around the parameter const square = x => x * x; // Short form for single expression function let sayHi = () => alert("Hello"); // No parameters
When there is only one parameter, () can be omitted. If body is single expression, rather than a block in braces, that expression will be returned from the function even without return statement.
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ? () => alert('Hello') : () => alert('Greetings');
Welcome();
// 18 is default,
// if less than 18, hello
// otherwise greetingsArrow Function with a Block (Multi-line)
If you need multiple statements in the function body, you must use curly braces {} and explicitly include the return statement.
const roundTo = (n, step) => {
let remainder = n % step;
return n - remainder;
};
let sum = (a, b) => {
let result = a + b;
return result;
};
alert(sum(1, 2)); // 3Arrow Function with No Parameters
When there are no parameters, use empty parentheses ():
const horn = () => {
console.log("Toot");
};Arrow Function as Arguments
Arrow functions can be used in the same way as regular functions, including as arguments to other functions.
function ask(question, yes, no) {
if (confirm(question)) yes();
else no();
}
ask(
"Do you agree?",
() => alert("You agreed."),
() => alert("You canceled the execution.")
);ask(
"Do you agree?",
function() { alert("You agreed.");},
function() { alert("You canceled the execution."); }
);Arrow Functions and this
Arrow functions behave differently from regular functions when it comes to the this keyword. They do not have their own this. Instead, they inherit this from the lexical scope (i.e., the surrounding context).
Arrow Functions Inheriting this
let user = {
firstName: "John",
sayHi() {
let arrow = () => alert(this.firstName); // `this` refers to the `user` object
arrow();
}
};
user.sayHi(); // Output: "John"In this example, the arrow() function inherits this from the sayHi() method, which refers to the user object.
Arrow Functions in forEach and Similar Methods
Arrow functions are useful in methods like forEach because they preserve the this context from the surrounding code:
let group = {
title: "Our Group",
students: ["John", "Pete", "Alice"],
showList() {
this.students.forEach(
student => alert(this.title + ': ' + student) // `this` refers to `group`
);
}
};
group.showList(); // Output: "Our Group: John", "Our Group: Pete", "Our Group: Alice"In this case, the arrow function inside forEach inherits this from the showList() method, which refers to the group object.
Regular Function in forEach
If we use a regular function inside forEach, the value of this changes to undefined in strict mode, or the global object (window in browsers) in non-strict mode:
let group = {
title: "Our Group",
students: ["John", "Pete", "Alice"],
showList() {
this.students.forEach(function(student) {
alert(this.title + ': ' + student); // Error: `this` is undefined or refers to the global object
});
}
};
group.showList(); // Error: Cannot read property 'title' of undefinedError because when forEach runs function with this=undefined by default. This doesn't affect arrow functions because they don't have this.
Here, the function passed to forEach does not have its own this and refers to the global context instead of the group object, leading to an error.
- Regular functions create their own
thiscontext, which means inside theforEachmethod,thisis no longer thegroupobject. - Arrow functions do not create their own
this; instead, they inherit it from the surrounding scope, making them ideal for cases like theforEachmethod where you want to preserve the context.
Arrow Functions Cannot Be Used as Constructors
Since arrow functions do not have their own this, they cannot be used as constructors. You cannot call an arrow function with new.
const Person = (name) => {
this.name = name;
};
let john = new Person("John"); // Error: Person is not a constructorIn this example, Person is an arrow function, and calling it with new will throw an error because arrow functions don't have their own this, which is required for object creation via new.
Summary of Arrow Functions
- Syntax: Arrow functions use the
=>syntax, making them more concise than regular function expressions. - No
thisbinding: Arrow functions do not have their ownthis. Instead, they inherit it from the surrounding scope, making them useful for methods likeforEach. - Single-expression functions: If the body is a single expression, the
returnkeyword is implicit, and you can omit the curly braces. - Cannot be used as constructors: Arrow functions cannot be invoked with
newbecause they do not have their ownthis.
Arrow Function Quick Reference
| Feature | Arrow Function | Regular Function |
|---|---|---|
| Syntax | () => expression | function() { return expression; } |
this Binding | Inherited from the outer scope (lexical this) | this is dynamic, based on the call site |
| Constructor | Cannot be used as a constructor (new is not allowed) | Can be used as a constructor |
Implicit return | Yes, for single expressions | No, needs an explicit return statement |
| Parameter Parentheses | Omit parentheses for a single parameter | Always require parentheses |
