Passing variables and objects in Javascript: Reference compared to Values
Tags: javascript, scope, learning, recursion
Published: 2021-03-07 03:34:25

## Motivation
I'm applying and interviewing for jobs right now and consequently brushing up on algorithms and data structures. This has led me to a lot of tinkering with recursion and backtracking. I'm a kinesthetic learner and keeping track of what's going on deep in a recursion stack makes my brain tired - so practice! This is **NOT** a blog about recursion and backtracking, although one of those may be here soon (In the meantime [here is a pretty good article on the subject](https://dev.to/christinamcmahon/recursion-explained-with-examples-4k1m).

All this practice has brought my attention to a Javascript feature (quirk) that I often forget about in these situations - Javascript's passing of values or references depending on the data type.

## Reference Vs. Value
When passing a variable that points to an object a *reference* to that object gets passed. When passing a variable that points to a number, boolean, string, or undefined the *value* of the variable is passed. Practically this means assigning multiple variables to an object will allow all of those variables to access the **same** object. This is not true with values. Quick example:
 
##
```javascript
let x = "Cheddar";
let y = x;
y = "Manchego"
console.log(x) //"Cheddar" 
console.log(y) //"Manchego"

let x = ["Cheddar"];
ley y = x;
y.push("Manchego");
console.log(x); //["Cheddar", "Manchego"]
console.log(y); //["Cheddar", "Manchego"]
```
We can get around this by using the spread operator:

```javascript
let x = ["Cheddar"];
ley y = [...x];
y.push("Manchego");
console.log(x); //["Cheddar"]
console.log(y); //["Cheddar", "Manchego"]
```
## Importance for Recursion
Okay, that's all well and good but what does this have to do with recursion? Well, to be perfectly honest, not much, but for me, it keeps coming up when refactoring iteration to recursion or visa-versa.

Let's take a look at the quintessential recursion example: Fibonacci (More info on the Fibonacci sequence available on the always helpful [Wikipedia](https://en.wikipedia.org/wiki/Fibonacci_number)).

Here's a quick function to return the nth term in the Fibonacci sequence:

```javascript
function fibonacci(n) {
  const dict = {};
  return calcFib(n, dict);
}

function calcFib(n, dict) {
  if (n === 1 || n === 2) {
    return 1;
  }
  if (dict[n]) return dict[n];
  result = calcFib(n - 1, dict) + calcFib(n - 2, dict);
  dict[n] = result;
  return result;
}
```
Notice that at every return we have to return the `result`. If we had chosen to make `result` an argument of `calcFib`, we would still need to return the `result` of the calculation. This is because when we pass down `result` to another instance of `calcFib` it is just the value `result` points to not the `result` we will eventually return. Another way to look at this is through the lens of our memoization dictionary, `dict`. We never return this value yet it remains updated through all instances of `calcFib`. This happens because `dict` is an object and so we are updating a reference to the location of `dict` in memory, not just the values contained in `dict`.

Let's look at a non-recursive version to see if we can clear this up. Here is an iterative function to return an array of the first n terms of the Fibonacci sequence.

```javascript
function calcFib(current, previous, result) {
  result.push(current + previous);
}

function fibonacci(n) {
  let result = [];
  //base cases
  if (n === 1) return result.push(1);
  if (n >= 2) {
    result.push(1);
    result.push(1);
  }

  for (let i = 1; i < n - 1; i++) {
    calcFib(result[i], result[i - 1], result);
  }
  return result;
}
```
Notice that in `calcFib` we don't return anything! We can get away with this because we are updating an array (which in Javascript is a type of object) and that means we are passing `calcFib` a reference to the `result` array. When we add another value of the sequence to `result` we are always updating the same object in memory. 

## Final thoughts
The 5-cent takeaway here: in Javascript objects are passed by reference, meaning they always point to the same object in memory even if being passed to another function with a different scope.  Everything else is passed by value, so if you are entering another scope and you want an updated value back make sure to return it! 

Thanks for reading and hope this saves someone a bit of debug time.