How to assign two Variables to the same Object
Tags: javascript, beginners, webdev
Published: 2019-12-12 14:48:27

Let's say we have an object and want to assign two different variables to it, we could do the following:

```javascript
const vala = 100
const valb = { life: 42 }

let a, b
a = b = { propa: vala, propb: valb }
```

The keen eye will have noticed one fatal flaw with this code: Changing `a.propa` will also change `b.propa`.
This is due to `a` and `b` both referencing the same object, it might be easier to notice if we wrote it like this instead:

```javascript
const vala = 100
const valb = { life: 42 }
const objectToClone = { propa: vala, propb: valb }

let a, b
a = b = objectToClone
```

The last line says we want `a` to equal `b` and `b` to equal `objectToClone`, so both `a` and `b` reference the same object. This might be fine for your purposes, but it's quite likely undesired behaviour.
Let's go over a few solutions to this problem:

```javascript
const vala = 100
const valb = { life: 42 }

let a = { propa: vala, propb: valb }
let b = { propa: vala, propb: valb }
```

This solution works as you might expect. You could change `a.propa` and `b.propa` would be untouched; indeed `a` and `b` reference different objects, of the same values.

However if you answer "yes" to the following question: Do `propa` or `propb` reference an object?, then you face another potential issue: Objects in JavaScript are passed by reference, not by value.

What does this mean? I'll point you to [this article](https://dev.to/steelvoltage/passed-by-reference-vs-value-in-javascript-2fna) to explain, but once you know what the difference is, continue below

So now you know what passing by reference means, you'll notice in our example, `valb` is an object. Our issue now is that if any changes happen to `valb`, they will be reflected in `a.propb` and `b.propb`.

So how do we get around this issue?

```javascript
const vala = 100
const valb = { life: 42 }

let a = JSON.parse(JSON.stringify({ propa: vala, propb: valb }))
let b = JSON.parse(JSON.stringify({ propa: vala, propb: valb }))
```

We have now made it so any changes to `a.propb` and `b.propb` don't affect each other, as they now reference different objects, with copies of the same values. This is thanks to the power of `JSON.parse` and `JSON.stringify`, I'll point you to [this post](https://stackoverflow.com/a/122704) for a run-down

Now this seems like an awful lot of code, just to assign two variables to different copy of the same object. So let's do better!

First we have the benefits of shorthand object property declarations in ES6:

```javascript
const vala = 100
const valb = { life: 42 }

let a = JSON.parse(JSON.stringify({ vala, valb }))
let b = JSON.parse(JSON.stringify({ vala, valb }))
```

This comes with the trade-off of having to now get the values of `a.propa`, `a.propb`, `b.propa` and `b.propb` with `a.vala`, `a.valb`, `b.vala` and `b.valb` instead.

_If you wanted too, you could change the `vala` and `valb` declarations to `propa` and `propb`, but that isn't semantic, so please don't do that!_

Next we can do the following:

```javascript
const vala = 100
const valb = { life: 42 }

let a, b
a = JSON.parse(JSON.stringify({ vala, valb })), b = JSON.parse(JSON.stringify(a))
```

Which we could collapse like so:

```javascript
const vala = 100
const valb = { life: 42 }

let a, b; a = JSON.parse(JSON.stringify({ vala, valb })), b = JSON.parse(JSON.stringify(a))
```

If you wanted to take it one step further, you can create an [VSCode snippet](https://code.visualstudio.com/docs/editor/userdefinedsnippets) like so:

```json
{
    "Two reference object copy": {
        "prefix": "troc",
        "body": ["let ${1:a}, ${2:b}; ${1:a} = JSON.parse(JSON.stringify(${3:obj})), ${2:b} = JSON.parse(JSON.stringify(${1:a}))", "${0}"],
        "description": "Declares two references to a copy of an object"
    }
}
```

This will allow you to type `troc` and type the name of the first reference declaration, hit tab, type the second, hit tab and finally type the object to clone for each reference
I hope this helps anyone who has come across this problem and wanted a solution

**Note**: *I am aware of the potential performance impacts of using the `JSON` methods. If you wanted to you could use [_.cloneDeep](https://lodash.com/docs/#cloneDeep) by [Lodash](https://lodash.com) to make this even more succinct.*

*However with most higher programming pursuits, less code usually involves higher impact to performance.*