Destructuring the 'this' object in JavaScript
Tags: javascript, this, node
Published: 2020-07-10 14:33:02

This is a short and simple trick for working with classes in JavaScript.  Many programmers including myself that are comfortable with Object-Oriented Programming concepts are used to working with classes. 

If you fall into this category then you probably like using classes in JavaScript like this:

```jsx
class MyClass {
  constructor(){
    this.message = "hello there"
  }
  
  printMessage = () => {
    console.log(this.message) // valid prints "hello there"
  }
} 
```


Even though this is just [syntax sugar](https://en.wikipedia.org/wiki/Syntactic_sugar) on top of regular prototype-based inheritance. I find it easier to read.

One specific issue I have with the syntax of JavaScript classes is how members of a class, like `message`, are referenced in member functions. 

In the example above we have to use `this.message` in `printMessage` even though `printMessage` is a member `MyClass` instance to reference `message`. 

It would be a lot nicer to just do the following:

```jsx
class MyClass {
  constructor(){
    this.message = "hello there"
  }
  
  printMessage = () => {
    console.log(message) // invalid prints undefined
  }
} 
```

It's a contrived example I know. But typing and reading `this.message` over and over and over again can be quite cumbersome if it is used in a function enough. 

Then I realized that we can just use destructuring on the `this` object of member functions. 

```jsx
class MyClass {
  constructor(){
    this.message = "hello there"
  }
  
  printMessage = () => {
    const {message} = this
    console.log(message)
  }
}
```

## Reference Types and Primitive Types

This approach has some drawbacks and gotchas when dealing with reference types and primitive types. It's good to be aware of them if you decide to do this. 

Let's look at this class definition:

```JavaScript
class MyClass {
  constructor(){
    this.message = "hello there" // primitive type
    this.items = [1, 2, 3] // reference type
  }
  
  printMessageMutable = () => {
    // copies the value of this.message into message
    let {message} = this
		
    console.log(this.message) // prints "hello there"
    console.log(message) // prints "hello there"
    
    // will not update this.message
    message = "there hello"
    
    console.log(this.message) // prints "hello there"
    console.log(message) // prints "there hello"
  }
  
  printMessageImutable = () => {
    const {message} = this
    console.log(message) // prints "hello there"
  }
  
  printItemsMutable = () => {
    // creates mutable a copy of the reference to this.items
    let {items} = this
    
    // both items and this.items reference the same array
    items.push(42)
    
    console.log(items) // prints [1, 2, 3, 42]
    console.log(this.items) // prints [1, 2, 3, 42]
    
    // now items and this.items reference different arrays
    items = [4, 5, 6]
		
    console.log(items) // prints [4, 5, 6]
    console.log(this.items) // prints [1, 2, 3, 42]
  }
} // MyClass
```

In `printMessageMutable` we create a local copy of `this.message`. That means that any changes to `message` in the function will not be reflected in `this.message`.  If we needed to update `this.message` in `printMessageMutable` this might not be the best place to use destructuring on `this`.

In `printMessageImutable` we create a constant copy of `this.message`. So we are only ever planning on using the value of `this.message` and can't try to update it using the local variable `message`. This is a great case for using object destructuring on `this`. 

In `printItemsMutable` we are updating an array. Arrays are reference types in JavaScript. When we call `items.push(42)` both `items` and `this.items` are referencing the same array. Because of this, both `items` and `this.items` will be updated.  Later we set the local variable `items` to a new array `[4, 5, 6]`. Now when we print `items` and `this.items` we get different values. That's because `this.items` is still pointing to the old array initially set in the constructor.  

## Conclusion 


That's it. I just think it's nice to be able to drop the `this.` especially if a member variable is used a lot in one function. However, it won't be appropriate for all use cases. 

Thanks for reading, let me know you disagree!