What is this thing called this?
Tags: javascript
Published: 2017-11-29 16:57:29

---
title: What is this thing called this?
published: true
description: Exploring `this` in JavaScript
tags: javaScript
---
The easiest way to describe `this` is that it refers to the object it's assigned *when called*. For example, consider this object:

    const song = {
      title: 'What is this thing called love',
      writer: 'Cole Porter',
      artist: 'Elsie Carlisle',
      performed_by: function(){
        return this.artist
      }
    }


When `song.performed_by()` method is called, `this` refers to `song`. **But before we actually execute the code, `this` refers to nothing**. 

Consider the following two lines: 

    console.log(this.someVariableName)
    console.log(someVariableName)

The first line outputs `undefined` and the second throws an error, telling us that `someVariableName` is undefined. If we define the variable without passing it a value, the output is the same in both cases

    console.log(this.someVariableName)
    let someVariableName;
    console.log(someVariableName)

Which tells us that `this` truly is waiting to be assigned to something. 

## Changing the context of `this`

A lot of people have sang the song over the years, let me tell you my current favorite versions: 

    let performers = [
      {
        artist: 'sant andreu jazz band',
        listen_at: 'v=kZS2Kx1Hr9I'
      },
      {
        artist: 'Rebecca Ferguson',
        listen_at: 'v=O0FwMORV2Og'
      }
    ]

When I run `song.performed_by` I want one of the above artists to be returned! We do this by using `call`, `apply` or even `bind`. 

This is my favorite version of that song:

    song.performed_by.call(performers[1])
    //or
    song.performed_by.apply(performers[1])

`this` in `performed_by` refers to another object, and so the output of the above code is `Rebecca Ferguson`. 

The difference between `call` and `apply` is how we pass arguments. In the above scenario there's no difference, but if we were to pass arguments, `apply` passes them as an array. 

## Lets do another example

Let's change the code a little bit so that we return the title and the artist. 

    let song = {
      ...
      performed_by: function(){
        return `${this.title} by ${this.artist}`
      }
    }
    let performers = [
      {
        artist: 'sant andreu jazz band',
        listen_at: 'v=kZS2Kx1Hr9I'
      },
      {
        artist: 'Rebecca Ferguson',
        listen_at: 'v=O0FwMORV2Og'
      }
    ]

Running `song.performed_by()` will return the title and the song. But running `song.performed_by.call(performers[0])` will return `undefined by sant andreu jazz band`, that's because `performers[0]` object doesn't have a title. Let's modify the code. 

    let song = {
      ...
      performed_by: function(value){
        let title = this.title ? this.title : value
        return `${title} by ${this.artist}`
      }
    }

We can add the title as an argument 

    song.performed_by.call(performers[0], 'What is this thing called love')

If we use `apply` the title would have to be passed as an array (and clearly, we'd have to reference it as `title[0]`

    song.performed_by.call(performers[0], ['What is this thing called love'])

## Using `bind` 

`bind` is similar to `call` but used when we want to assign `this` to an object without calling it

    let announcement = function(title){
        return `${title} by ${this.artist}`
    }.bind(performers[0])
    announcement('What is this thing called love')

In fact, the above snippet perfectly demonstrates the difference between `call` and `bind`

    let announcementFunction = function(title){ ... }.bind(performers[0])
    let announcementValue = function(title){ ... }.call(performers[0])

Because of `call` the anonymous function has executed and the value is attached to `announcementValue`

Useful places to use `bind` might be on event listeners

    document.querySelector('a').addEventListener('click', theMan.bind(song) )

Then we create `theMan` which would take anything inside the `song` object

    const band = function(){
        return `${this.artist} band`
    }.bind(performers[0])
    function theMan(e){
        console.log(`${this.writer} wrote a great song 
            and the girls from ${band()} sing an amazing cover`)
    }

When we click the anchor tag, we get the message `Cole Porter wrote a great song and the girls from sant andreu jazz band sing an amazing cover`

---
That's it, thanks for reading. Also, if you are anything like me when it comes to music, you'll like the youtube links I listed