JavaScript Stuff I Thought Was Weird Which Just Turned Out to Make Sense After All
Tags: javascript, objects, primitives
Published: 2020-12-15 16:03:43

---
title: JavaScript Stuff I Thought Was Weird Which Just Turned Out to Make Sense After All
published: true
description: 
tags: javascript, objects, primitives
//cover_image: https://direct_url_to_image.jpg
---

When I first started learning JavaScript, I definitely had a beat-it-to-fit, paint-it-to-match mentality. My wrangling of code was basically just elbow grease and duct tape, and I filed a lot of things away as cute little mysteries, assuming that JavaScript kept as them a personality quirk.

![keep your secrets](https://i.imgur.com/EckGOhe.jpeg)

But it turns out, most of the stuff that I thought was totally bonkers, actually does make sense when you get down to the brass tacks of it.

I'm writing this post about a favorite example of this. Here are two code snippets which are true:


```javascript
let uno = 1

function topple (arg){
	arg += 1 
}

topple(uno)

console.log(uno)
	=> 1
```

and 

```javascript
let arr = []

function topple (arg){
	arg[0] = "toodledoo"
}

topple(arr)

console.log(arr)
	=> ["toodledoo"]
```

As a newbie programmer, *this made absolutely no sense*. In one case, you pass an argument and perform an alteration, and it does not change the variable. In the second case, it totally does change the variable. I'm also a bootcamp grad, so at the time I really had to pick my battles for which topic I could do a deep dive into, and this was not one of them. I settled for memorizing the truth that you could change arrays and hashes, but for some reason you couldn't get the same functionality out of variables pointing to a string or a number. I'm...perhaps a little *too* good at going with the flow, so for a while I chalked it up to a silly weird thing left it at that. 

Since I've had a little more time and a lot more freedom to explore topics of interest, I've found some super fascinating things out about that code. 

Firstly, I learned that in JavaScript, there are a limited number of **types** that any one piece of code can be. Here are all of them:

1. String
2. Number
3. Boolean
3. Object
4. Function
5. Undefined
6. Null
7. Symbol
8. Bigint

And that's it. Everything you touch and see and get slapped with in the form of an error message is gonna be one of these things. For the purposes of explaining the weirdness above, I'm really just going to talk about `Numbers` and `Objects`.

Before moving on, it's paramount to define `Objects`, because I feel like that gets thrown around a lot with different meanings. In terms of the underlying skeleton of JavaScript, MDN Docs defines an `Object` like this:

> In computer science, an object is a value in memory which is possibly referenced by an identifier.

Which, is just, so useless. What does that even mean? You may have heard elsewhere that "everything in JavaScript is an object," and I feel like that's closer. That's almost true. Arrays, hashes, regex, these are all objects. Importantly, `Objects` are mutable.  Changeable. Hashes and arrays can alter their contents constantly.

There are a few things in JS that are *not* `objects`, and `numbers` are one of them. 

`Numbers` are considered a special sort of thing in JS, called a "primitive." Primitives are immutable. Can you change the value of one? Think for a sec, what if you add 1+5...Does 1 stop being 1? Nope, 1 will always exist, in its primitive state, unchanging. 

So, that brings us back around to our examples. Let's take a deeper look into the first example.

```javascript
let uno = 1

function topple (arg){
	arg += 1 
}

topple(uno)

console.log(uno)
	=> 1
```

Step One: Set a variable called `uno` which points to the primitive `number` 1.

Step Two: Define a function which accepts an argument, and in the body of the function, permanently increases that argument by 1.

Step Three: Call function. Hand it our `uno` variable. This step is where the secret magic happens that I previously didn't understand. I was saying things like "hand it a variable" but failing to realize that you can't hand *anything* a variable in JavaScript. You hear that craziness? You go around for a couple years of your life thinking that you pass information in your code around using variables and it's a total lie. **You *can't hand anything a variable* in JavaScript**.

It's because variables are instantaneously evaluated. In step three, we aren't handing that function anything called `uno`, we are handing it a tiny puzzle, which JavaScript works out right then and there in the arguments. It follows `uno` back to the source and finds out that we set it to point to the number 1, and it actually just passes the number 1 through to the body of the function. The reason that our variable is unchanged on the other side of the function is that our body never saw nor touched the variable.

Okay. Now, that is super cool, and very exciting to be able to see the secrets of JavaScript happening in real time -- I imagine this is how I would feel if I could watch human bones and tendons interacting with perfect clarity under the skin of a living person. I wonder if surgeons get this feeling.

But we still have another mystery on our hands: If this first example can't alter the variable, why in God's green earth would it be able to alter the second one, in a nearly identical example?

Remember what we talked about with the mutable items versus the non-mutable items. As we said before, there is only one 1. You can't change the number 1, and any time you reference it, you are always pointing at the same ol' number 1. One symptom of being mutable is the ability to be *multiple*. Because arrays can change, they can have many different instances that exist in different places in your computer's memory. You can get a really good visual of this by running a short test in your browser's console. First, run this code:

```javascript
for(let i=0;i<10;i++){
     console.log(1)
}
```

Notice the result. Now don't clear your screen, and run this code:

```javascript
for(let i=0;i<10;i++){
     console.log([])
}
```

With the first one, you see the number 1 with a little 10 to the left of it, indicating that the number was logged 10 times in a row. What's up with the next one? Why does it show ten arrays logged on separate lines?

Right, it's not repeating anything. *Those are all different arrays*. 

Cool, so it's possible that you've already put together where I'm going with this, but might as well finish it out. Let's dive into the second example like we did the first.

```javascript
let arr = []

function topple (arg){
	arg[0] = "toodledoo"
}

topple(arr)

console.log(arr)
	=> ["toodledoo"]
```

Step One: Set a variable called `arr` which points to some new  `object`.

Step Two: Define a function which accepts an array, and in the body of the function, permanently adds "toodledoo" to that array.

Step Three: Call function. Hand it our `arr` variable.

But! As we know, you can't pass variables anywhere in JS. So `arr` will get evaluated right then and there, and JavaScript will instead pass the array itself into the body of the function. And here's where it all comes together: 

Because you can have multiple arrays in a single coding project, and because each individual array holds a different place in memory, when our function adds "toodledoo" into the array that it's given, that changes its value in the actual computer. So when we go to check the variable again, it doesn't try to grab a new array, it goes back to the place in memory where our array was stored and finds that this particular instance has been changed. 

To recap: If you pass a function the number 1, it can't change that number at all. Even if you set 10,000 variables to the number 1, they'd all be pointing to the same place in memory, cause nobody can mess with math. However, if you pass a function an `object` such as an array, all new objects point to a different place in memory, so if you change that array you can still see the changes later down the line.

Fascinating, like I said. Now, one last thing. This code is also true:

```javascript
let uno = 1

function topple (){
	uno += 1 
}

topple()

console.log(uno)
	=> 2
```

Why do you think that is?




-------------------------------------
-------------------------------------
*All credit to Dan Abramov and his wonderful newsletter for helping me become a more enlightened programmer.*