loading...

What is this thing called this?

aurelkurtula profile image aurel kurtula ・3 min read

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

Posted on Apr 3 '18 by:

aurelkurtula profile

aurel kurtula

@aurelkurtula

I love JavaScript, reading books, drinking coffee and taking notes.

Discussion

markdown guide