There are so many ways in Javascript for defining a function. The usual way is by Function Declaration or Function Expression
//function declaration
function foo(){
console.log("Hello from foo!!")
}
//function expression
const bar = function(){
console.log("Hello from bar!!")
}
The Difference between Function Declaration and Function Expression.
Function Declarations are hoisted in global Context and Function Expressions in temporal dead zone, which mean you can access Function Declaration before its initialization in code but you Function Expression before it initialize in the code
Note: other than the Above difference they both work as the same so we can reference them as Regular Functions.
What are Arrow Functions?
Arrow function is a compact way of writing Functions Expression but is limited and can't be used in all situations.
const bar = () => {
console.log("Hello from bar!!")
}
Difference between Regular Function and Arrow Functions?
A. This keyword value
- In Regular functions,
this
or execution context` value depends upon how the function is invoked.
const username = {
name: "Mayank Gupta",
sayname:function(){
console.log(this.name)
}
}
username.sayname() // Mayank Gupta
const newuser = {name:"Gagandeep Singh", age:50}
username.sayname.call(newuser); // Gagandeep Singh
- An arrow function does not have its own execution context .
this
value in the arrow function always be equal to this value from the outer(lexical context
) function.
const username = {
name: "Mayank Gupta",
sayname: () => {
console.log(this.name)
}
}
username.sayname() // here this is equal to global object so it log window object
const newuser = {name:"Gagandeep Singh", age:50}
username.sayname.call(newuser); // here this is equal to global object so it log window object
B. Arguments
- In Regular function body have access to a special array-like object called
arguments
which contains the list of an argument with which function is invoked.
function logArguments(){
console.log(arguments)
}
logArguments(1,2,3) // [1,2,3, length ....]
- Where Arrow does not have access to this special object.
const logArguments = () => {
console.log(arguments)
}
logArguments(1,2,3) // ReferenceError: arguments is not defined
C. Constructs
- Regular functions can easily form constructors because
this
resolve as the execution context
function Pet(type) {
this.type = type;
}
const myDog = new Pet("Dog")
myDog instanceof Pet; // true
- Whereas, Arrow functions cannot form constructors because
this
resolves as lexical context.
const Pet = (type) => {
this.type = type;
}
const myDog = new Pet("Dog") // TypeError: Pet is not a constructor
D. Methods
- Most of the time Regular functions are used to define methods on classes .
function Pet(type, legs) {
this.type = type;
this.legs = legs;
this.logInfo = function() {
console.log(`The ${this.type} has ${this.legs} legs`);
}
}
const myDog = new Pet('Dog', 4);
myDog.logInfo() // The Dog has 4 legs
It is working fine here but if you supply a method to Callback
or an Eventlistener
it will create an issue. as you can see in the below example
setTimeout(myDog.logInfo, 1000) //The undefined has undefined legs
After 1 second it will log global window object or undefined because the method gets separated from the object. Now if the method is invoked without an object then this is a global window
object or undefined in strict mode
. you can fix context by binding this object to its own method.
const boundLogInfo = myDog.logInfo.bind(myDog);
// logs "The dog has 4 legs"
setTimeout(boundLogInfo, 1000);
- In Arrow Functions, this problem is resolved because as you know now no matter how a function is invoked
this
value is always equal tothis
value from the outer function.
function Pet(type, legs) {
this.type = type;
this.legs = legs;
this.logInfo = () => {
console.log(`The ${this.type} has ${this.legs} legs`);
}
}
const myDog = new Pet('Dog', 4);
setTimeout(myDog.logInfo, 1000) //The Dog has 4 legs
If you have any doubts regarding this please reach out at Twitter
Happy Coding💻