Re-Realizing context
Tags: javascript, programming, web
Published: 2021-06-09 12:56:07

---
title: Re-Realizing context
published: true
description: "Explicitly setting this with .call(), .apply(), .bind()"
tags: javascript, programming, web
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eplqwqbo5me5g8uvj5nc.jpg
canonical_url: https://jaygurav.netlify.app/chaitime/reRealizingContext/
---

Often when getting started into programming most seasonal developers struggle their way into understanding `this` (especially in functional languages) and get into all sort of troubles that even further messes up things, however "this" becomes easy when they understand that `this` is all about the _context of invoking_ a function rather than confusing yourself with from where it was declared(which is mostly the case in Object Oriented language).

> It ain't what you don't know that gets you into trouble, Its what you know for sure that just ain't so -Mark Twain

If you find above terms difficult not to worry they are themselves a fully fledged topics to write an article or even a [book](https://www.oreilly.com/library/view/you-dont-know/9781491905142/) to get into nitty-gritty details of `this`

In this post we'll try to learn about one of the implicit binding and how to explicitly set/bind context (`this`).

## Implicit Binding

Implicit binding is when the context of invoking `this` is internally, intentionally and automatically bound to something else. These are considered as default standards/rules of how `this` behaves, for example

`this` with a getter or setter is one such example of implicit binding, consider another example below

```js
function greet() {
  // this === userDetails //true
  console.log(`Hello ${this.fullName}!`) //Hello Jay Gurav!
}

const userDetails = {
  fullName: "Jay Gurav",
  greet,
}

userDetails.greet()
```

When a function is called as a method of an object, its this is set to the object the method is called on. So in the above example `greet` method on object `userDetails` has `this` internally bounded to the object which invokes the function as its method using `.` operator, so the `this === userDetails` would result to true in `greet` function when called using `userDetails.greet()`. It to important to note that only the last property matters, so something like below

```js
function greet() {
  // this === userDetails //false
  console.log(`Hello ${this.fullName}!`) //Hello John Doe!
}

const userDetails = {
  fullName: "Jay Gurav",
  greet,
}

const dummyUserDetails = {
  fullName: "John Doe",
  greet: userDetails.greet,
}

dummyUserDetails.greet()
```

Here even if the greet property on `dummyUserDetails` points to `userDetails.greet` the `this` here in this case would be `dummyUserDetails` and not `userDetails`. So always remember in case of objects `this` refers to the object on which the method is invoked.

## Explicit binding

so as the title says to **re-realize context** or to explicitly set `this` to some another context of our wish, JavaScript provides us with three useful methods `.bind()`, `.call()` and `.apply()` available to all functions through `Function.prototype` object to do so.

So we can achieve something that we intended to do above as follows

```js
function greet() {
  console.log(this === userDetails) //true
  console.log(`Hello ${this.fullName}!`) //Hello Jay Gurav!
}

const userDetails = {
  fullName: "Jay Gurav",
  greet,
}

const dummyUserDetails = {
  fullName: "John Doe",
  greet: greet.bind(userDetails),
}

dummyUserDetails.greet()
```

Here we explicitly say that we want to bind the method (not function) `greet` on `dummyUserDetails` with the context of `userDetails`.

## call

The `call` method on `Function.prototype` object call a function with the provided context assigned to this, and the following arguments passed to the function as its arguments list.

`Function.prototype.call ( thisArg, ...args )`

The `thisArg` value is passed without modification as `this` value to the calling function. However it is important to note that when `undefined` or `null` is passed as `thisArg` then it is replaced with the global object and if the function is an arrow function then the `thisArg` will be ignored by the function.

for example

```js
function log(ps) {
  console.log(`${ps} ${this.name}`)
}

const product = {
  name: "cheese",
}

const myPet = {
  name: "Bruno",
}

log.call(product, "Yummy") //Yummy cheese.
log.call(myPet, "🐶") // 🐶 Bruno
```

## apply

The `apply` method on `Function.prototype` object calls a function with the provided context assigned to this, and the array/array-like-object passed as the second argument that is passed to the calling function.

Function.prototype.apply ( thisArg, argArray )

> Note that the syntax of `.call()` and `.apply` is almost identical , the fundamental difference is that `.call()` accepts an argument list while `.apply` accepts a single array of argument.

so in the above example we could be doing something like `log.call(myPet, ["🐶", "🐰"])`

## bind

The `.bind()` method on `Function.prototype` object creates and returns a brand new function that when called has its `this` set to the provided context and the following arguments passed to the function as its arguments list.

`Function.prototype.bind ( thisArg, ...args )`

consider this below example

```js

const user = {
  name: "John Doe",
  age: 42,
  getUser: function (){
    return {name: this.name, age: this.age};
  }
}

const user2 = {
  name: "Jane Doe",
  age: 25,
}

const globalContextUser = user.getUser;
globalContextUser() //{ name: undefined, age: undefined }


const boundedUser = globalContextUser.bind(user); //{ name: "John Doe", age: 42 }

const boundedUser = globalContextUser.bind(user2); //{ name: "Jane Doe", age: 25 }
```

> 📚 Further reading and resources
>
> - [Ecma specification](https://262.ecma-international.org/11.0/#sec-properties-of-the-function-prototype-object)
> - [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) on .apply(), .call(), .bind()


👉 This blogpost was originally publish at my personal [blog site](https://jaygurav.netlify.app/chaitime/reRealizingContext/)

### Get in touch
Hey, have any suggestions, questions or concerns, You can find me [Twitter](https://twitter.com/JayMGurav), [GitHub](https://github.com/jaymgurav/) and [LinkedIn](https://www.linkedin.com/in/jaymgurav). Help me make this better!, Feel free to drop me a message and I’ll get back to you soon Thanks!🎉