TIL - Spread and Copying Objects in Javascript
Tags: todayilearned, javascript, tutorial, learning
Published: 2020-08-11 12:57:48

## Background

This is a part of a series of writing a tutorial of what I learn everyday. I try to learn something new related to CS and programming everyday and I believe that writing some sort of post, report, or tutorial from memory really solidifies the understanding and makes it stick in your brain.

# Today I learned...

How to utilize the spread operator and how copying objects in Javascript work. 


What do you think the code below will output?

```javascript
let obj = {
    prim: 2,
    anotherObj: {
        val: 'red'
    }
}

let truck = { ...obj }
truck.anotherObj.val = 'blue'
console.log(truck.anotherObj.val) 
console.log(obj.anotherObj.val)
```

It turns out that the "val" within "anotherObj for both truck and obj will be "blue". This is a bit confusing since shouldn't the two objects be separate since they are stored in separate variables?

## Deep vs Shallow Copy

In Javascript, all primitive types are assigned and passed by value, but all objects are assigned and passed by reference. This explains why in the previous code block changing the value of a property of an object resulted in the copy of the object to have its property updated as well.

```javascript
let obj = {
    prim: 2,
    anotherObj: {
        val: 'red'
    }
}

let truck = { ...obj }

truck.prim = 123123 
console.log(truck.prim) // 123123
console.log(obj.prim) // 2
```

In this case since we are modifying the "prim" property which is a primitive type it is not reflected across the other object since in Javascript, primitive types are assigned by value not reference.

## What does by reference mean?

Passing or assigning by reference means that when copied the new variable holds a reference or "points" to the space in memory where the original object lies. This means that any changes to either the original object or anything that references it changes the values within the original object.

## Shallow copies

Using the spread operator or Object.assign() you can create shallow copies of objects!

```javascript
let obj1 = {
    testing: 'testing'
    nestedObj: {
        nestedTesting: 'nestedTesting'
    }
}

let obj2 = { ...obj1 }
```

As seen above, the spread operator is "...".

## Deep copies

When another object is created with a deep copy, any nested objects are newly created so they don't share the same reference. This means that changes to the copy of the object are not reflected in the original object since a new object is created for the copy.

A way to perform a deep copy is to use the [lodash clonedeep](https://www.npmjs.com/package/lodash.clonedeep) package.

## Merging Objects

Merging objects can also be performed with the spread operator.

```javascript
let obj1 = {
    name: 'obj1',
    testing() {
        console.log(this.name)
    }
}

let obj2 = {
    name2: 'obj2',
    testing2() {
        console.log(this.name)
    }
}

const obj3 = {...obj1, ...obj2} // obj3 has all of the properties in both obj1 and obj2
```

A thing to note is that if there are properties with the same name in the objects, the value of the last object with that property gets assigned.