# Learning Journey Node.js: thoughts on arrow functions

Up until this point in my career as a JavaScript/Frontend engineer, I've tried to just follow along with best practices as expressed via popular articles, library/package documentation, and any coursework I find myself leveling up with. I haven't typically given much forethought to "why" something is considered a best practice.

Until now... :D.

I'm currently going through a Node.js course ([The Complete Node.js Developer Course](https://www.udemy.com/course/the-complete-nodejs-developer-course-2)), authored by [Andrew Mead](https://www.udemy.com/user/andrewmead/) and [Rob Percival](https://www.udemy.com/user/robpercival/) (great work on the course, BTW, gents! :) ). In my career, thus far, as a Frontend engineer, I've mostly stuck to frontend frameworks and technologies that are mainstream: Angular 1.x, then Angular 2+, followed by React/TypeScript. In that time, I've used **function** syntax:

```javascript
function getSquaredNumber(x) {
  return x * x;
}

console.log(getSquaredNumber(2)) // 4
```

...as well as **arrow-function** syntax:

```javascript
const getSquaredNumber = (x) => {
    return x * x;
};

console.log(getSquaredNumber(2)) // 4
```

...as well as the ES6 **method definition** syntax:

```javascript
const numberUtils = {
  getSquaredNumber(x) {
    return x * x;
  },
};

console.log(numberUtils.getSquaredNumber(2)) // 4
```

It would be easy to believe that each of these functions simply flavors of the same base **function** syntax. After all, they all produce the same results. Yet, there are some meaningful ways in which they are different.

### THIS Context

If you're working with object-oriented programming syntax, you might find yourself using `this` keyword to access a property on that object. As an example:

```javascript
const person = {
  name: 'Nathan',
  getName: function() {
    console.log(this.name);
  },
};

person.getName(); // "Nathan"
```

Invoking `person.getName()` results in logging the string `"Nathan"`. This is because `this` is within the context of the `person` object; therefore `this.name` refers to the value at the `person.name` property.

Ok... so what's the big deal?

While the `getName` property method has the context of the `this` keyword, if we change it to an **arrow function**:

```javascript
const person = {
  name: 'Nathan',
  getName: () => {
    console.log(this.name);
  },
};

person.getName(); // undefined
```

Now invoking `person.getName()` results in logging `undefined`. But why? Aren't the method syntaxes synonymous? Well, if you're smart (not like me), you'd discover that the **arrow function** inherits its parents' context. In this case, no `name` property of its parent context has been defined. This is what that'd look like:

```javascript
this.name = 'Johnny'

const person = {
  name: 'Nathan',
  getName: () => {
    console.log(this.name);
  },
};

person.getName(); // "Johnny"
```

Now invoking `person.getName()` results in logging `"Johnny"`. That's because the **arrow function** is inheriting the `this` from its parent context (which is the block of JavaScript above).

Why use **arrow functions** at all then?

A lot of the time **arrow functions** are useful when you want to maintain the context of the parent context.

Let's say for example that we are trying to iterate through a list of people, and log out their names:

```javascript
const person = {
  name: 'Nathan',
  getName() {
    return this.name;
  },
  friends: [
    'Bobby', 'John', 'Kevin', 'Joey',
  ],
  listFriends() {
    // log out the friend list
  },
};
```

We could try to use the **function** syntax:

```javascript
const person = {
  name: 'Nathan',
  getName() {
    return this.name;
  },
  friends: [
    'Bobby', 'John', 'Kevin', 'Joey',
  ],
  listFriends() {
    this.friends.map(function(friend){
      console.log(`${this.name} is friends with ${friend}`);
    })
  },
};

person.listFriends();
// " is friends with Bobby"
// " is friends with John"
// " is friends with Kevin"
// " is friends with Joey"
```

Using the **function** syntax results in 4 console logs of `" is friends with [friend name]"`. Why is the `person.name` not being listed? This is due to the `function() {}` having its own `this` context. The variable `friend` is scoped to the **function** since it's the **callback value** of the `map` function, but `this.name` is in the context of the parent `listFriends` function.

Solution...

If we replace the `function(friend) {}` with an **arrow function**, the **arrow function** will inherit the `this` context from the `listFriends` ES6 **method definition** syntax, and bob's your uncle.

```javascript
const person = {
  name: 'Nathan',
  getName() {
    return this.name;
  },
  friends: [
    'Bobby', 'John', 'Kevin', 'Joey',
  ],
  listFriends() {
    this.friends.map((friend) => {
      console.log(`${this.name} is friends with ${friend}`);
    })
  },
};

person.listFriends();
// "Nathan is friends with Bobby"
// "Nathan is friends with John"
// "Nathan is friends with Kevin"
// "Nathan is friends with Joey"
```

### Why does this matter?

It used to be that when you were working with promises and callbacks you had to **bind** context down through the callback functions. It was hell.

With the **arrow function**, however, you can treat the nested functions as being part of their parent, but having code isolation from other **arrow functions** since they have their own scope, but inherit from their parent. This is incredibly useful for reducing bleed effects across your code as you use functional patterns.

Hope this helps in your journey. :)
