(Fat) Arrow Functions

We all wrote a lot of functions but let's start with a simple one that adds two arguments.

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

Of course, everything is correct and compliant with ES5 standards. At the outset, I will also point out that if someone liked a syntax in how the functions in JavaScript were created so far, they do not have to change everything. The ES5 way is as correct as it was but ES6 has some facilities that can make life a bit easier.

Now a code sample on how we would write it following with ES6 standards.

const add = (a,b) => {
  return a + b;
}

As you can see, two things have changed. First of all, we took out the keyword function, and secondly, we added the Arrow Function ( => ) after the parameters. By some people, it is also called the Fat Arrow Function. This indicates that the arrow is created using an equal sign. An interesting fact is also that there is a so-called thin-arrow in CoffeeScript. It differs in that instead of the equal sign it appears as you probably guess the dash.

We could end here, and I would try to encourage everyone to switch to the new ES6 version. However, if someone wants to know quite an important difference, I encourage you to read a few more lines.

We could try to do it in even more fancy way.

const add = (a,b) =>  a + b;

Ok, let me use the function I have already shown in the previous series (JavaScript Part 16).

var myObject = {
  name: "Name of my object",
  method: function() {
    this.name = "I changed my name!";
    console.log(this);

    var changeName = function(newname) {
      this.name = newname;
    }
    changeName("I changed my name once again !");
    console.log(this);
  }
}

myObject.method();

As you can remember (or not) that for our last console.log to returna a changed name for the second time, we had to use a trick that looked like this.

var myObject = {
  name: "Name of my object",
  method: function() {
    var self = this;
    self.name = "I changed my name!";
    console.log(self);

    var changeName = function(newname) {
      self.name = newname;
    }
    changeName("I changed my name once again !");
    console.log(self);
  }
}

myObject.method();

Another way would be to use the bind function, which I wrote about in the last part of the previous series. It would look like this.

var myObject = {
  name: "Name of my object",
  method: function() {
    this.name = "I changed my name!";
    console.log(this);

    var changeName = function(newname) {
      this.name = newname;
    }.bind(this)

    changeName("I changed my name once again !");
    console.log(this);
  }
}

myObject.method();

In both of them, we would get what theoretically we want and theoretically how it should be.

Before I show you how simple and easy it is to get the desired effect (this pointing to the object a function is in) let's modify primary code a bit .

const myObject = {
  myName: "Name of my object",
  doSomeNameMagic: function() {
    this.myName = "I changed my myName!";

    console.log('name: ', this.myName);

    const changeName = function(newname) {
      console.log('this value inside changeName function: ', this);
      console.log('this.myName (theoretically/practically we want the myName of the myObject object) ', this.myName)
      console.log('new myName: ', newname);
      this.myName = newname;
      (function() {
        console.log('this value inside IIFE #1 ', this);
      })();
    };

    changeName("I changed myName once again !");

    console.log('name after changeName: ', this.myName);
  },
};

I know, I know that's a lot of consoles.logs, but I find it as the best way to figure out what is happening at a given moment. Let's go. First console.log after invoking a doSomeNameMagic method ( myObject.doSomeNameMagic(); ) on the myObject will log us new value of myName. Since a doSomeNameMagic function is attached to the object (same way as myName), this variable will point to the object it is attached. In our case - myObject.

Inside the doSomeNameMagic function, we are doing a little bit more. The changeName function is created and invoked with an argument - "I changed myName once again !". So since we are invoking it let's check the results of 3 console.logs inside it.

The first thing that catches the eye (first line) is that the value this points to a global object, not a myObject. This is how the so-called standalone functions behave. In our case, it will be a browser window object. Since this indicates the window object where there is no information about the variable myName, it should be obvious that the value we get is undefined. The last console.log, however, simply returns the value of the argument passed to changeName.

The next console.log (in IIFE) will also point to the global object for the same reason as above - standalone function, which is simply the so-called IIFE (first picture below). Since in the changeName of the function there was no information about the variable myName, the change failed and the last console.log will simply return the old value.

Although in a moment we will go to Arrow Function, it is worth remembering how this works in javascript before introducing Arrow Functions. Often you will want to use the old syntax (for example Vue.js, but about that maybe next time).

The third and most on-time way is to use just the Arrow Function.

var myObject = {
  name: "Name of my object",
  method: function() {
    this.name = "I changed my name!";
    console.log(this);

    var changeName = (newname) => {
      this.name = newname;
    }

    changeName("I changed my name once again !");
    console.log(this);
  }
}

myObject.method();

When we decide to solve it using ES6, it is worth knowing how special variable this works. Well, it is quite simple, the Arrow Function does not have its own this value. This value takes on the value of what the Arrow Function is in. So for example, if We wrote a doSomeNameMagic function as an Arrow Function, this would point to ... You guessed - window object. Arrow Functions shine exactly in those moments when anything that requires this to be bound to the context and not the function itself.

Next Post

We will talk about Classes in ES6.