JavaScript Interview Prep: Primitive vs. Reference Types
Tags: javascript, career, beginners
Published: 2019-07-26 19:39:20

[*original article*](https://itnext.io/javascript-interview-prep-primitive-vs-reference-types-62eef165bec8)
In a JavaScript interview, they might ask if you understand the difference between *primitive* and *reference* data types. Luckily for you, this topic is one of the few in computer science where the names explain it all. There are two ways data types can store info: as a slot in memory, or as a reference to a slot in memory somewhere else. Can you guess which is which?

# First up: Primitive types
Primitive data types are: numbers, strings, booleans, undefined, and null (also [symbols](https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/) so check those out). Basically, if it's storing a simple piece of data, it's stored simply. When you set a variable with this type, the variable is that exact value and that's all. If you change that value, the variable simply becomes a new value.

# Next: Reference Types
That means the two reference types are objects and arrays (technically one, since [arrays are objects](https://stackoverflow.com/questions/5048371/are-javascript-arrays-primitives-strings-objects)). When you create an object, that value is not directly assigned to the variable. Instead, a *reference* to that value is what gets set. All that variable knows about is the location of the object, not the object itself.

# Explaining it with a chore metaphor
Let's say you need to remind yourself to clean the dishes. If you were to store it primitively, you would take a piece of paper and write down "do the dishes." But what if your roommate already did them? Now your chore is take out the trash. Since it's primitively stored, you just take that piece of paper, erase "do the dishes" and write down "take out the trash."

To save your chores by reference, your roommate would keep a list of all the chores. When you need to know what's left or cross one off, you ask them, and they access the list. You don't have the list yourself, you just know where to find it. But enough with metaphors, let's look at some code.

# Code that copies a value is where it counts
This all really comes into play when copying or transfering values. Look at this code that copies primitive values:

```js
let color1 = 'green';
let color2 = color1;
color1 = 'purple';
console.log(color1);
// 'purple'
console.log(color2);
// 'green'
```

`color1` is assigned the string value `'green'`, which means the variable `color1` is essentially the same as just a string `'green'`. When we use `color1` to assign a value to `color2`, it would've been the same as if we literally assigned it a string value. So when we reassign `color1`'s value, it has absolutely no impact on `color2`. Both values were always just saving strings, they had no lasting bonds between them. This is not the case with reference types. Look:

```js
let car1 = {
  wheels: 4,
  seats: 2,
};
let car2 = car1;
car1.brand = 'ford';
console.log(car1.brand);
// 'ford'
console.log(car2.brand);
// 'ford'
```

Huh. We never assigned `car2` a brand property, yet it has one. Despite the situations looking the same as our primitive example, the behavior is the opposite. That's because `car1` was never assigned the *value* of the object, only the *reference* to it. So if you change `car1`, that will alter the same spot in memory that `car2` is looking at:

![](https://thepracticaldev.s3.amazonaws.com/i/ii3oru3a17pfzvzdcw48.png)

# Solving the reference problem
By adding that brand property, we permanently altered the original object. That is called a _mutation_, and it's not great when we accidentally do it to more than our intended target. To get around this, we just have to create a new reference to a new object. That way, each variable will point to its own object and not have any overlap. The most common approach is to use Object.assign or the spread operator. For brevity, let's use a spread:

```js
let car1 = {
  wheels: 4,
  seats: 2,
};
let car2 = {...car1};
car1.brand = 'ford';
console.log(car1.brand);
// 'ford'
console.log(car2.brand);
// undefined
```

# One last thing
Objects are mutable, meaning they can change (unless you [freeze it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze). However, primitive types are [immutable](https://www.sitepoint.com/immutability-javascript/). See, you can't actually mutate the number `1` into `2`, you just replace the value. Meaning we didn't change our `'green'` string, we just straight up replaced it with a new string, `'purple'`. It's a sneaky little technicality, but now you know! So good luck on those interviews and as always,

Happy coding everyone,

Mike

*Like this? I have [more articles](https://medium.com/@mikecronin92)*