What's the difference between arrow functions and regular functions?

pedrogustavo

Pedro Gustavo

Posted on August 3, 2023

What's the difference between arrow functions and regular functions?

Sometimes, after using a pattern so much, we end up forgetting the real reason why we write our code in that way. My intention in this content is to remind you (or show you for the first time) the main differences between a "regular" function and an arrow function.

Starting from the beginning... What is a function anyway?

What is a function?

I would call a function a "mini program". It's nothing more than a piece of code created for a specific purpose. The syntax is quite simple; for that, you need to use the function keyword.

Here's an example of a function that prints "Hello World!" to the console:


function helloWorld () {
    console.log('Hello World!')
}
Enter fullscreen mode Exit fullscreen mode

Alright, now that we are all on the same page, let's get to the point!

What is an arrow function?

Starting from ES6, a new syntax possibility was introduced in JavaScript, called "arrow function." It allows us, among other things, to write reduced code, without the need to use the function keyword.

To achieve the same result as the previous code example using an arrow function, we would have the following code:

const helloWorld = () => console.log('Hello World!')
Enter fullscreen mode Exit fullscreen mode

However, besides the difference in syntax, there are other differences that I want to present to you. These are the main ones you should be aware of to avoid unwanted issues.

Main differences

Context

Arrow functions have a dynamic this, meaning "their own this". On the other hand, regular functions inherit the context from where they were declared. Let me illustrate to clarify the explanation:


const testFunction = {
  number: 42,
  func: function() {
    return this.number
  }
}
console.log(testFunction.func())
// Output: 42

const testArrowFunction = {
  number: 42,
  func: () =>  {
    return this.number
  }
}
console.log(testArrowFunction.func())
// Output: undefined
Enter fullscreen mode Exit fullscreen mode

In the case of the regular function, it absorbs the context of its declaration and, in this case, recognizes the property "number". Whereas the arrow function, as it "creates its own this", looks for the "number" property within itself and, since it doesn't find it, its return is undefined.

Constructor

Arrow functions cannot be constructors; it's not possible to make a call using the new operator:


const regular = function() {}
const arrowFunction = () => {}

new regular() // safe...
new arrowFunction() // Error: arrowFunction is not a constructor
Enter fullscreen mode Exit fullscreen mode

Arguments

Due to lexical context, arrow functions do not have access to the arguments object. For example:


function regular() {
  return arguments
}
console.log(regular('potato', 'rice')) // { 0: 'potato', 1: 'rice' }

const arrowFunction = () => {
  return arguments
}
console.log(arrowFunction('potato', 'rice')) //{ 0: 'potato', 1: 'rice' }
Enter fullscreen mode Exit fullscreen mode

Arrow functions do not have their own arguments. They have access to the arguments of the nearest parent "regular" function.

Return

Arrow functions give you the possibility of making a shortened return without explicitly using the return keyword.


// example 1
function regular () {
  return [1, 2, 3]
}

const arrowFunction = () => [1, 2, 3]

// example 2
function regularObj () {
  return { foo: 1 }
}

const arrowFunctionObj = () => ({ foo: 1 })
Enter fullscreen mode Exit fullscreen mode

Hoisting

JavaScript hoists "regular" function declarations to memory before executing any part of the code. This allows you to use the function before its declaration. With an arrow function, this is not possible, as they are anonymous and assigned to a variable. Therefore, this allocation before code execution doesn't happen. See the example:


console.log(regular()) // 'regular function'

function regular () {
  return 'regular function'
}

console.log(arrowFunction()) // Error: Cannot access 'arrowFunction' before initialization

const arrowFunction = () => 'arrow function'
Enter fullscreen mode Exit fullscreen mode

To make the same code work correctly, you would need to change the order of the arrow function declaration as follows:


const arrowFunction = () => 'arrow function'
console.log(arrowFunction()) // 'arrow function'

Enter fullscreen mode Exit fullscreen mode

Conclusion

Well, I hope to have clarified your mind regarding the use of arrow functions in JavaScript. Sometimes, we forget about the differences in using functions and may end up spending hours debugging errors in our code, all due to carelessness or in pursuit of a simplified syntax.

Be attentive to the presented points and let's code!!!

💖 💪 🙅 🚩
pedrogustavo
Pedro Gustavo

Posted on August 3, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related