# Javascript's "this" binding

```this```  keyword in Javascript can sometimes be confusing due to lack of proper knowledge. Here I am going to discuss how ```this```  work. 

    
```this``` belong to a Javascript function. Inside a function this keyword refers to an object.

```
var a = 4;
function fun() {
    console.log("a = ", this.a); // a = 4
}
fun();
``` 
In the above code chunk ```this``` in fun() body refers to global object and as any variable that is globally declared belongs to global object, so ```this.a``` is 4.
This is **Default Binding** of ```this```.

**Note:**  If strict mode is used inside the function body using  ```this``` , then by default ```this``` will refer to ```undefined``` instead of global object.

** What ```this``` refers to only depends on the how the function is called.**

Another rules for ```this``` binding

**Implicit binding**
    
```
var prop = 2
function fun1() {
    console.log(this.prop)
}
var obj = {
    prop: 1,
    fun: function fun() {
        console.log(this.prop)
    },
    fun1: fun1
}

obj.fun(); // 1
obj.fun1(); // 1
fun1(); // 2
```
```
var obj = {
    prop: 1,
    fun: function fun() {
        console.log(this.prop)
    },
}

function containing(cb) {
    cb()
}

obj.fun(); // 1
containing(obj.fun) // undefined
```


Here for both ```obj.fun()``` and ```obj.fun1()``` ```this``` is binded to ```obj```.  This is **Implicit binding** when one object is used as context object when the function is called. 

```
var obj = {
    prop: 1,
    fun: function fun() {
        console.log(this.prop)
    },
}

var fun1 = obj.fun
fun1();
``` 
But implicit binding of ```obj.fun``` is lost here because all that matters is how ```fun``` is called. Here ```fun1``` is holding only a reference to ```fun``` function just like ```fun``` property of ```obj```. As ```fun1``` is called as ```fun1()``` so ```this``` keyword refer to global obj or ```undefined``` depending on strict mode.

**Explicit Binding**

If we want to call a function with a object as context , without defining function reference property inside the object, we will have to use explicit binding.
Here is ```call()``` and ```apply()``` is our options

```
var obj = {
    a: 1
};

function fun(b, c) {
    console.log(this.a);
    console.log(b);
    console.log(c);
}

fun.call(obj, 2, 3); // 1 2 3
```
here ```call``` takes an object which is referenced by ```this``` and will invoke the ```fun``` with parameters which are passed to  ```call()```.

```apply()``` behave similarly except it takes a single array as arguments instead of list of arguments

```
var obj = {
    a: 1
};

function fun(b, c) {
    console.log(this.a);
    console.log(b);
    console.log(c);
}

fun.apply(obj, [2, 3]); // 1 2 3

```

** new Binding **

```new``` keyword can be  used with all the functions to create new objects.

```
function fun(a) {
    this.prop = a;
}

var obj = new fun("val");
console.log(obj.prop); // val
```

when a function is invoked with ```new``` in front of it , it will create a new object and bind ```this``` to the newly created object.


** Lexical this **
In case of arrow functions these rules does not work. Arrow-functions adopt ```this``` binding from enclosing function or global scope.

```
function fun() {
    setTimeout(() => {
        console.log(this.a);
    }, 100);
}

function fun1() {
    setTimeout(function () {
        console.log(this.a);
    }, 100);
}

var obj = {
    a: 2
};

fun.call(obj); // 2
fun1.call(obj) // undefined
```
the arrow function which is passed to setTimeout  lexically captures ```this``` of ```fun```s at it's call time

** Finally here is the summary of the rules described above to determine ```this``` binding**
This is the order of precedence

1. if the function is called with ```new``` then ```this``` refers to newly created object
```
var obj = new fun();
```
2. if the function is called with ```call``` or ```apply``` then ```this``` refers to explicitly provided object to call or apply.
```
fun.call(obj);
```
3. if the function is called with a context obj then ```this``` refers that obj.

```
var obj = {
    a: 1,
    fun: function () {
        console.log(this.a)
    }
}

obj.fun() // 1
```

4. Default binding. In strict mode ```this``` refers to ```undefined``` and without strict mode it refers to global object

```
fun();
```



