Troll Hunting 101: JavaScript Passes Objects by Reference
Tags: javascript, typescript, functional, codequality
Published: 2020-08-22 03:33:35

Sometimes I fall into the trap of thinking that I've seen it all.  I may not know every technology.  But I'm usually familiar with all the major movements-and-mindsets that pulsate throughout the programming communities.  

So I was quite shocked recently when Dev.to introduced me to an entirely different species of troll.  One I'd never encountered in my quarter century of programming experience.  

I'm talking about the pass-by-reference troll.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lxxeuereuanjvivxp6nd.png)
## How I Discovered the Pass-by-Reference Troll Species
I was writing an article, right here on this site, about cloning objects in JavaScript.  (You can read it here: https://dev.to/bytebodger/cloning-objects-arrays-in-react-5475)  I gave the following example:

```javascript
const phantomMenace = { master: 'palpatine', apprentice: 'maul' };
const attackOfTheClones = phantomMenace;
attackOfTheClones.apprentice = 'dooku';
console.log(phantomMenace.apprentice);  // dooku(!)
```  

Before the code example, I made this statement:
<br/>

> In most programming languages, objects (and their nephews, arrays) are passed by reference.

<br/>To be honest, I never really gave any more thought to it as I wrote the rest of the article.  To me, saying that "in most programming languages, objects are passed by reference" is akin to saying that "in most lakes, the water is wet."  This wasn't some radical new idea I was putting into the blogosphere to challenge traditional mores.  It was a basic statement of Dev 101.

Then a particular commenter latched onto my post, starting with his contention that almost _no_ languages feature pass-by-reference.  And that JavaScript has _no_ pass-by-reference.  And that I apparently have no idea how JavaScript - or any other language works.  And the commenter was _adamant_.  

To be clear, the commenter wasn't particularly accurate.  Nor persuasive.  First, they started sending me examples _in Java_ - as though Java and JavaScript are interchangeable.  Then they started telling me that code I put in my examples didn't do what I said it would do (it absolutely did - and I had the StackBlitz's to prove it).  Then they just kept diving into circular arguments - even going so far as to put up their own code examples that only served to illustrate _my_ point.

Nevertheless, this particular commenter was so vehement that it actually led me to question my premises.  Had I been misunderstanding a critical detail for most of my professional life?  After all, I want to be open-minded.  And _anything's_ possible...  

So I reached out to a friend of mine.  He's about 20 years younger than me (so he has none of that old-guy stink in his thought patterns).  And he's one of these guys who _thinks_ in code.  He's highly entertained by esoteric questions of coding _theory_.  He's basically a prodigy.  And quite frankly, he's a far better programmer than I.  So I shot him this basic question:
<br/>

> ME: Hey, sorry for the silly, basic, theoretical question, but I gotta ask this as part of a little personal experiment:  In JavaScript, objects are passed by... value?  By reference?  By... something else??  It's not a trick question.  What is your knee-jerk answer??

<br/>Within a minute or two, he replied:
<br/>

> PRODIGY FRIEND: By reference

<br/>A few minutes later, he elaborated with this:
<br/>

> PRODIGY FRIEND: Pass an object into a function and then change `someObject.someProperty` and the original object in the original scope will also change.  Was someone arguing this point with you?  LOL

<br/><br/>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ayjjd411w7xdkzlj36yt.jpg)
## Troll Sightings in the Wild
Initially, I brushed off this "rogue commenter".  I'd never heard _anyone_ else go so bat-shit crazy about such a _basic_ concept in programming.  And then... I started seeing more of them.  Here.  On Dev.to.  (And, curiously enough, _only_ on Dev.to - don't know exactly what that means.)

And they're jerks.  I'm sorry to put it in such confrontational terms.  But it's true.  They feel compelled to jump on any post they can where someone dares to claim that JavaScript objects are passed by reference.  And many of their responses are pedantic bullying, where they expect _you_ to prove that _they're_ wrong.  

At first, I had a really hard time even describing some of the ridiculous comments I saw on this site with regard to pass-by-reference.  But then it hit me.

You know what the JavaScript Pass-By-Reference Trolls are _just like_???
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uje6fa6wu2xrbhqzazoq.jpg)
## Knowledge is the Enemy
Do pass-by-reference trolls and flat-earthers have their own dating app?  Do they send each other secret admirer letters?  Are they _the same_ people???

If you've ever tried to argue with a flat-earther, you know that it's an exercise in futility.  They won't listen to anything you say.  They will unrepentantly use all manner of logical fallacies.  They don't mind mashing up examples from _any_ scientific discipline to "further" their objectives.  

One day, you go to sleep content in the knowledge that some ideas have been so universally _proven_ that they cannot be refuted as scientific **fact**.  The next day, you have some belligerent flat-earther moron sitting at your table telling you that you must prove to him every aspect of your ridiculous and specious understanding (the same "understanding" that's upheld _by every scientist and educated individual on the face of the planet_).

It's quite the same with JavaScript's pass-by-reference trolls.  Once they hear you commit the Cardinal Sin of discussing JavaScript's pass-by-reference, they will pounce.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t8adaudfk9h4rntqu16z.jpg)
## An Epic Waste of Time
When I was first trying to treat these people seriously, I tried to make the case as dead-simple as possible:

```javascript
// Are you telling me that THIS:
const phantomMenace = 'first movie';
let attackOfTheClones = phantomMenace;
attackOfTheClones = 'second movie';
console.log(phantomMenace); // first movie

// Is functionally no different than THIS???
const phantomMenace = { master: 'palpatine', apprentice: 'maul' };
const attackOfTheClones = phantomMenace;
attackOfTheClones.apprentice = 'dooku';
console.log(phantomMenace.apprentice);  // dooku(!)
```

In both examples, we have an original variable.  A second variable was created, initialized by the first variable.  The second variable was then mutated.  And... here's where the examples are unique:  In the first example, the original variable _is unchanged_.  In the second example, the original variable absolutely _is_ changed.  

The difference is that, in the first example, the values are _primitives_.  Primitives are _always_ passed by value.  Another way to think of "passed by value" is that the value is passed _as a fresh copy of the original_.

But in the second example, the values are _objects_.  Objects are _always_ passed by reference.  Another way to think of "passed by reference" is that the value passed _is a pointer to the original value_.  You know what's another name for "pointer"???  _Reference_

I don't know how I could make it any clearer than that.  And yet, I gave this exact example to a pass-by-reference troll and asked him, "Are you telling me that the values in _both_ of these examples are passed by value??"  And he said, "Yes."
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6iglc7lfdyqohde68jlc.jpg)
## Rules Lawyers
Although it's honestly difficult to follow most of their dogmatic rantings, one thing is clear:  Many of them revel in being _rules lawyers_.  They don't seem to care so much about how code _works_ (like: in the example shown above).  They care about pedantic details about how code is _defined_.  In stodgy spec documents.

One example of this is when they say things like:
<br/>

> Please show me _in the ECMAScript spec_ where it says...

<br/>Nope.  Uh-uh.  Not even going there.  My _working code sample is above_.  I don't care about the exact terminology that someone chose to use when writing a spec doc as part of a bureaucratic open-source committee.  

I don't doubt that the words "pass by reference" might not actually exist in the ECMAScript spec.  That in no way overrides the empirical fact that I can illustrate objects being passed by reference in the extremely simple example above.

I don't care so much about the exact verbiage chosen when people decided to write out a lengthy spec.  I care about how the code _actually works_.  

I don't know if the Java spec actually uses the words "object-oriented language".  Maybe it does. Maybe it doesn't.  I honestly couldn't care less.  Even if those words exist nowhere in the Java spec, the simple fact is that Java _is_ an object-oriented language.  

Similarly, I really don't care if the words "pass by reference" exist in the JavaScript spec.  JavaScript _does_ pass objects by reference.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i105bnoh9b4pzmkaor2g.jpg)
## What is the Meaning of "is"??
The pedantics don't stop with snobbish references to the ECMAScript spec.  Some of the trolls wanna challenge the meaning of the word "value".  They typically say something like this:
<br/>

> When you set one variable equal to an object, it's still set _by value_. It's just that the _value_ is a reference to another object.

<br/>Yes.  I've heard/read that _exact_ effery.  This is not some sad joke.  It's a banal reality.

Under this mindset, there is no such thing, in the entire programming world - or even in any other part of the physical world - as a "reference".  Because, under this thinking, _every_ "reference" is, in itself, a type of "value" (that holds... a _reference_).  

Now I'm sure that Plato and Socrates would love to toss that distinction around for a few decades while they work out the difference between "a reference" versus "a value - _that holds a reference_".  

But I don't have the time to wait for dead philosophers to figure out whether trees, falling in the woods, actually make a sound if no one is there to hear it. I have to write code.  And meet deadlines.  And explain esoteric coding concepts to junior developers.  

When I'm trying to show a new developer the difference between the two examples shown above, you can sure-as-hell bet that I don't tell them, "You see... It turns out that _all_ of these variables are passed by value!  And you'll just have to pray to some ancient god to determine why the behavior is so different."
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hi5kiy523iuymbgni9mf.jpg)
## The Pedantry of "Passing"
The pedantry doesn't stop at the definition of "value".  The trolls also wanna argue about "pass".  Under this strain of trollishness, the argument goes:
<br/>

> In your examples shown above, there is no "passing" taking place - because there are no functions.

<br/>OMFG.

Despite what you may surmise from these blogs, I actually speaka de English reals good.  And I know what "pass" means.

Yes, I thoroughly understand that, in programming, "passing" often refers to the idea that we pass arguments into functions.  But when you do this:

```javascript
const firstVariable = 'foo';
const secondVariable = firstVariable;
```

There is nothing logically incorrect in saying that we have _passed_ the value of `firstVariable` into the initial state of `secondVariable`.  If that's not your preferred verbiage, then fine - whatever.  But that doesn't mean it's _wrong_ to say that the value of `firstVariable` was _passed into_ `secondVariable`.

But let's set aside the Merriam-Webster definitions of "passing" for a moment.  Because even if we accept that pass-by-reference and pass-by-value can only apply when we are passing values into a function, JavaScript **_STILL_** passes by reference!

Wanna argue with me, trolls??  Here's the oh-so-simple example:

```javascript
const myObject = {
  one: 'uno',
  two: 'dos',
};
const myString = 'marco';

const myFunction = (theObject, theString) => {
  theObject.one = 'einz';
  theString = 'polo';
}

myFunction(myObject, myString);
console.log('myObject', myObject); // {one: 'einz', two: 'dos'}
console.log('myString', myString); // 'marco'
```

Inside `myFunction()`, when `theObject` is mutated, the change is reflected back in `myObject`.  Wanna know why??

_Because JavaScript passes objects by reference._

Also inside `myFunction()`, we mutated `theString`.  But that change was _not_ reflected back in `myString`.  Wanna know why??

_Because JavaScript passes primitives by value._
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wrpy43pd4qiw1p0n1twu.jpg)
## More Than Terminology
It's tempting to paint this as just a simple mismatch in terms.  Nothing more than a misunderstanding, if you will.  

We could say that JavaScript objects are "copied as pointers".  And that JavaScript primitives are "copied as literals".  For some minds, that _might_ be a clearer definition.  Depending upon your chosen dogma, it might sit easier on your mind.

But... no.  That's BS.  Sorry (not sorry), but it just is.

You see, if you wanna argue that a "reference" is just "a _value_ that holds a reference" - then you're gonna argue the same thing about a "pointer".  To be clearer, if you wanna make this kinda argument, then... you just enjoy arguing.

And if you have a problem with "pass" because you think it can only possibly be applied _to functions_ - well then... you just don't have a solid grasp of the English language.  I'm sure that sounds snarky and combative - but it's absolutely true.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s3nbwvza2dpcq5719u6v.jpg)
## The Power of Words
This rant may lead you to believe that I don't care at all about technical definitions or that I play fast-and-loose with jargon.  But nothing could be farther from the truth.  

In all areas of life, but _especially_ in tech, I fully understand that words can have extremely specific meanings.  And that botching those meanings can have real world consequences.  

But I also understand that words portray _concepts_.  If we focus on the words for the sake of arguing about specific words, then we've missed the entire point.  Language only has meaning _in context_.

So when you wanna get on your rules-lawyering high horse about passing by reference, or passing by value, you need to keep in mind one extremely basic - and tactical - fact.  It would seem, on the surface, that these two examples should behave in the exact same way:

```javascript
// Are you gonna telling me that THIS:
const phantomMenace = 'first movie';
let attackOfTheClones = phantomMenace;
attackOfTheClones = 'second movie';
console.log(phantomMenace); // first movie

// Is functionally no different than THIS???
const phantomMenace = { master: 'palpatine', apprentice: 'maul' };
const attackOfTheClones = phantomMenace;
attackOfTheClones.apprentice = 'dooku';
console.log(phantomMenace.apprentice);  // dooku(!)
```

But of course... they do _not_ behave in the same way.  In the first example, the changes to the mutated _object_ are reflected back _on the source object_.  In the second example, the changes to the mutated _string_ are _not_ reflected back on the source string.  Why???<br/><br/>

> **Because primitives in JavaScript are passed by value.  And objects in JavaScript are passed by reference.**

<br/>If you think that the examples above are operating under the exact same principle - that _all_ the variables are passed by value - well... good luck to you.  Enjoy yelling at people over pedantic details for the rest of your life - details that only you, with your heroic knowledge, can possibly understand.

[FINAL NOTE:  This will be the 53rd article I've published on Dev.to.  I've always taken pride in answering most of the comments that are left on my blogs.  For this particular article, I won't be responding - to anything.  I've learned from reading around on this subject that the "there is no pass by reference!" crowd can be, quite honestly, jerk-wads.  (Technical term.)  And I have no desire to engage with the flat-earthers for another round of pigeon chess.]