Lately, I’ve been trying to brush up on my JavaScript basics and within that, I realized I had a difficult time explaining the main differences between arrow functions and regular functions (declarations and expressions). Let’s take a look at some key differences!
“This”
Regular Functions
A very important difference between arrow functions and regular functions is what this references when the function is invoked. In a regular declarative function, this will point to the global object (window).
function example(){
console.log(this)
}example() //=> logs the global object
However, this in normal functions is dynamic. If we console.log this inside of a method function, we will log the object the method belongs to.
const anotherExample = {
exampleMethod() {
console.log(this)
}
}
anotherExample.exampleMethod() //=> logs anotherExample
Arrow Functions
In arrow functions, this always points to the value of the outer function. Arrow functions look lexically and because of this, they do not define their own execution context, which will come up in a little bit.
const exObj = {
exFunc() {
console.log(this) //===> logs exObj
const arrowFunc = () => {
console.log(this) //===> logs exObj
}
}
}
Constructors
One very important thing to note, arrow functions can not be used as a constructor. This is because of the lexical scoping we just referenced. If you try to use an arrow function as a constructor, you’ll get an error.
Hoisting
Normal functions are hoisted when they are declarative.
function name(string){
console.log(`My name is ${string}`)
}
//=> this will hoist
However, functions as expressions will not be hoisted.
const name = function(string){
console.log(`My name is ${string}`)
}
//=> this will not be hoisted
And since arrow functions are always written as expressions, they are never hoisted. For more on hoisting, check out here.
I hope this was helpful!