Find the player (javascript, this keyword)
Tags: javascript
Published: 2020-07-05 17:43:47

# Intro

A short blog about how you can determine the values of ***this*** keyword.
A confusing js concept (at least for me), **Kyle Simpson** and his book series "You don't know JS" made it more clear to me.
I hope that the following blog might help you to understand how this keyword works (I hope the same for myself :) ).

## What is a this

In order to understand the this **keyword**, a good start is to get rid of what you know about this keyword in any other languages.
Now, in js each function when is executed has an execution context, you get access to this execution context by using the **this** keyword (so it is an execution context).

## How you can determine the **this**

In order to determine the values/properties (bindings) that the **this** keyword has, you need to know two things:

1. **where** the function was called (location)
2. **How** the function was called

let's see how the ''this'' properties are determined (context bindings).
(All the context determination happens at the runtime).

## Default binding

Default binding is the simplest form, you just invoke the function from the global scope/object (window).

```javascript
function findThePlayer() {
    console.log(this.player);
}

var player = "Tsimikas: left back";

findThePlayer();
```

Determination procedure:

1. From **where** the function called? from the global scope
2. **how**? just a simple call
3. From 1 and 2, we determine that the execution function context is the global context
4. global scope has a player variable definition, so **this** has also a binding to that player

```sh
Kostas Tsimikas is printed!!
```

## Implicit binding

In the Implicit binding, the execution context is determined from the object (e.g. the call would look like *object.function()*).

```javascript
function findThePlayer() {
    console.log(this.player);
}

var player = "Kostas Tsimikas: left back";

var iniesta = {
    player: "Andres Iniesta: midfielder",
    findThePlayer: findThePlayer
};

iniesta.findThePlayer(); // implicit binding, Andres Iniesta: midfielder
```

Determination procedure:

1. From **where** the function called? from the global scope
2. **how**? the function call made by using an object reference
3. The execution context is the object (e.g. iniesta), isn't the global
   (explicit binding takes precedence over the default binding)
  
```sh
Andres Iniesta: midfielder, is printed!!
```

If we had invoke the function without the object, the output would be, Kostas Tsimikas: left back

## Explicit binding

In the Explicit binding, the execution context is directly assigned by passing the context to call() function
(e.g. the call would look like *function.call(context)*).

```javascript
function findThePlayer() {
    console.log(this.player);
}

var iniesta = {
    player: "Andres Iniesta: midfielder"
};

var mane = {
    player: "Sadio Mane: forward"
};

findThePlayer.call(iniesta);
findThePlayer.call(mane);
```

Determination procedure:

1. From **where** the function called? from the global scope
2. **how**? both functions are performed by assigned the context directly (e.g. iniesta and mane)
3. The execution context in both cases is the context that we pass explicity by using the call() function
   (explicit binding takes precedence over the default binding)

## new binding

In the new binding, a whole new context is created. Just by calling a function with the new keyword.

```javascript
function player(name) {
    console.log(this.giovanni);
    this.name = name;
}

var giovanni = "Giovanni Silva De Oliveira";
var messi = new player("Lionel Messi: forward");
console.log(messi.name);
```

1. From **where** the function called? from the global scope (doesn't matters in this case)
2. **how**? function called by the *new* keyword
3. In this case a new whole *this* is generated

In the above example, when you try to print the *giovanni* variable you are getting the value *undefined*.
This happens due to the use of the *new* keyword.

## explicit vs implicit binding

When you invoke a function by using an object and explicitly specifying the context (e.g. using call() function),
the the execution context would be the context that you have assigned in the call().  

```javascript
function findThePlayer() {
    console.log(this.player);
}

var iniesta = {
    player: "Andres Iniesta: midfielder",
    findThePlayer: findThePlayer
};

var mane = {
    player: "Sadio Mane: forward",
    findThePlayer: findThePlayer
};

iniesta.findThePlayer.call(mane);
```

The above script will print *Sadio Mane: forward* (explicit bind wins implicit)

## To sum up

how to determine the *this*:

1. if there is a *new* keyword in the function call, a new execution context is created
2. Explicit binding: calling a function using the *call* function and providing the execution context
3. Implicit binding: calling a function using an object, the execution context is the object
4. simple function call, the execution context is determined by the location that the function was invoked
5. Explicit wins implicit

Cheers!