Functions and Arrow Functions in JavaScript
Tags: javascript, webdev, beginners
Published: 2021-03-14 06:13:44

![Image that shows the Function expression and Arrow function expression](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8x80aym73resf0pvnun.png)

## Intro

Multiple ECMAScript (also very popular as JavaScript) editions introduced by ECMA-262 language specification throughout the time but ES5 (ECMAScript 2009) and ES6 (ECMAScript 2015) editions were significant.

Regular functions were there to define a function in ES5 version of JavaScript and Arrow functions were introduced in ES6 version.

Let us understand what are regular functions and arrow functions in JavaScript.

### ES5 (ECMAScript 2009)


##### Traditional function expression
`function [name]([param1[, param2[, ..., paramN]]]) {
   statements
}
`

Traditional function expression is used to define a function. The function keyword can be used to define a function inside an expression.

```js
var addition = function add(a,b) {
    return a + b;
}

console.log(addition(10,20));
// expected output: 30

```

Or, Function Constructor is used to defining a function. The Function constructor creates a new Function object. Function constructor creates functions that execute in the global scope only.

```js
var deduction = new Function('a','b', 'return a-b;');

console.log(deduction(15,5));
// expected output: 5

```

### ES6 (ECMAScript 2015)

Of course, we can use the traditional way of defining a function but the arrow function is introduced in ES6. A function can be declared without the function keyword by simply using parenthesis. An arrow function expression is a compact alternative to a traditional function expression, but is limited and can't be used in all situations.

#### Arrow Function Expressions

##### Basic Syntax

- One param. With simple expression return is not needed:
`param => expression
`

- Multiple params require parentheses. With simple expression return is not needed:
`(param1, paramN) => expression
`

- Multiline statements require body brackets and return:
`param => {
     let a = 1;
     return a + param;
}
`
- Multiple params require parentheses. Multiline statements require body brackets and return:
`(param1, paramN) => {
   let a = 1;
   return a + param1 + paramN;
}`


### Using Traditional Function Expression


```js
// using function keyword (traditional way)
var printHello = function () {
    console.log('Hello!');
}

printHello();
// expected output: Hello!

```


### Using Arrow function expression

```js
let printHello = ()=>{
    console.log('Hello!');
}

printHello();
// expected output: Hello!

```


### Differences & Limitations:

- Does not have its own bindings to **this** or **super**, and should not be used as methods.
- Does not have **arguments**, or **new.target** keywords.
- Not suitable for **call**, **apply** and **bind** methods, which generally rely on establishing a scope.
- Cannot be used as **constructors**.
- Cannot use **yield**, within its body.


### Arrow Functions and this keyword

##### With a Regular Function

‘**this**’ referred to the parent of the function in ES5.
```js
let person = {
    name: 'John Doe',
    myMethod: function () {
        console.log(this);
    }
}

person.myMethod(); //this === person object
// expected output: person object

```

##### With an Arrow Function

in ES6, arrow functions use lexical scoping, ‘**this**’ refers to it’s current surrounding scope and no further. Thus the inner function knew to bind to the inner function only, and not to the object’s method or the object itself.

```js
let person = {
    name: 'John Doe',
    myMethod: () => {
        console.log(this);
    }
}

person.myMethod(); // this === Window object

// expected output: Window object
```


Let’s go through with this example too.


```js
const myObject = {
    myArrowFunction: null,
    myMethod: function () {
        this.myArrowFunction = () => {
            console.log(this);
        }
    }
}
// let’s initialize the myArrowFunction
myObject.myMethod(); // this === myObject


myObject.myArrowFunction(); // this === myObject
// expected output: myObject object

```

Traditional function expression is used for the **myMethod** property. Thus, in that function **this** refers to **myObject** object.

When we initialize the **myArrowFunction** property with the arrow function, **this** refers to **myObject** object.