What Is an Arrow Function in JavaScript? How Is It Different From a Regular Function?
October 27, 2022
Arrow function is a function expression introduced in ES6. Some features of an arrow function are different from a regular function expression. It is a common question in JavaScript interviews, so make sure you know the difference.
The difference between arrow function and regular function
There are four main differences between arrow functions and regular functions, which we will explain in detail below:
- The syntax of the arrow function is different. It is more concise
- The arrow function does not have its own binding to
this
, and we cannot directly changethis
in an arrow function - Arrow functions do not have their own
arguments
- Arrow functions cannot be used as constructors. Calling them with new throws a TypeError
The syntax is more concise
Compared with regular functions, the syntax of arrow functions is more concise. In addition to eliminating the function
keyword, if there is only one parameter, we can omit the parentheses; if there is only one line of code, it simply returns a variable or a simple expression directly, and the curly braces and return
can be omitted. Examples are as follows:
// regular function
let addOne = function (n) {
return n + 1;
};
// ES6 arrow function, when there is only one parameter, the parentheses of the parameter can be omitted
let addOne = (n) => {
return n + 1;
};
// ES6 arrow function, when there is only one line, omit curly braces and return
let addOne = (n) => n + 1;
this value is different from a regular function
An arrow function does not have its own this
binding. The this
value of an arrow function is determined at the beginning of its definition. In an arrow function, this
is lexically scoped, meaning it is inherited from the parent scope. Also, we cannot use call
, apply
and bind
to bind this
value in arrow functions, the bound value will be invalid. The this
value of a regular function is determined based on how the function is called. For details, please refer to "What is the value of this in JavaScript".
this
can be bound in regular functions (code example)
const obj = {
num: 100,
};
window.num = 2020;
const add = function (a, b, c) {
return this.num + a + b + c;
};
// Bind this value to obj, obj's num is 100, so resultCall is 106
const resultCall = add.call(obj, 1, 2, 3);
console.log(resultCall); // 106
The this
binding in the arrow function will be invalid, the following is an example of the code binding
const obj = {
num: 100,
};
window.num = 2020;
const add = (a, b, c) => this.num + a + b + c;
// Binding this is invalid, the this of the add function will be window
// So num will be 2020 and resultCall will be 2026
console.log(add.call(obj, 1, 2, 3)); // 2026
Taking advantage of the fact that arrow functions do not have their own this
value, it is very suitable for use in setTimeout()
and EventTarget.prototype.addEventListener()
and other methods, because it will be automatically bound in its lexical scope. You can see that in setTimeout
below, there is a difference between this
using regular functions and arrow functions:
// regular function version, this value is NaN in this case
const obj = {
count: 10,
doSomethingLater() {
setTimeout(function () {
// It is a regular function, so this points to window
this.count++;
console.log(this.count); // NaN (because there is no count in windoww)
}, 300);
},
};
obj.doSomethingLater();
// arrow function version
const obj = {
count: 10,
doSomethingLater() {
// It is an arrow function, so this will be based on the this value of the closest parent, here is obj
setTimeout(() => {
this.count++;
console.log(this.count); // 11 (obj's count is originally 10, 10++ will be 11)
}, 300);
},
};
obj.doSomethingLater();
Do not have its own arguments
Unlike regular functions, arrow functions do not have an arguments
object, but the advantage is that arrow functions can get the arguments
object of the nearest non-arrow function, as shown in the following example
arguments
code example in arrow function
// Arrow functions don't have their own arguments, so they look for their parent
// The parent layer here is the global environment, so find the arguments variable in the global environment
// arguments[0] is 1 in the global environment
const arguments = [1, 2, 3];
const arr = () => arguments[0];
arr(); // 1
// A regular function has an arguments object, which is the parameter passed in. The arguments here are [3]
// so arguments[0] will also be 3
// f() would be 3 + 3
function foo(n) {
const f = () => arguments[0] + n;
return f();
}
foo(3); // 3 + 3 = 6
If you need to use all the parameters of the arrow function, you can use the following rest operator to get them
let nums = (...nums) => {
console.log(nums);
};
nums(1, 2, 3, 4, 5); //[1,2,3,4,5]
Cannot be used as a constructor
Arrow functions cannot be used as constructors, in other words, they cannot be called with the new
keyword or an error will be reported
const arrowFun = () => {};
new arrowFun(); // error: arrowFun is not a constructor
Summarize
- The syntax of the arrow function is different. It is more concise
- The arrow function does not have its own binding to
this
, and we cannot directly changethis
in an arrow function - Arrow functions do not have their own
arguments
- Arrow functions cannot be used as constructors. Calling them with new throws a TypeError