DEV Community

Cover image for Mutant Ninja References (vs Copies)
mzakzook
mzakzook

Posted on • Edited on

3 1

Mutant Ninja References (vs Copies)

Are your functions pure? Mine weren't. I had developed a less-than-desirable habit of creating reference variables when I should be creating array/object copies. What do you expect to see printed to your console for the following code?

let arrayOne = [1, 2, 3];
let arrayTwo = arrayOne;
arrayTwo[1] = 10;
console.log(arrayOne === arrayTwo); // -> ?

If you guessed 'true', you are correct. The variable 'arrayTwo' is simply a pointer to the memory location of 'arrayOne', which is why modifying 'arrayTwo' mutates 'arrayOne'.

Via GIPHY

Mutations can be cool, especially when they involve crime-fighting turtles and large amounts of pizza, but it's best to avoid them as much as possible with our code. This is an issue that is only of concern with memory-accessed variables (like arrays and objects). Here is another example where a reference variable can pose problems...

function mutateTurtle(turtle) {
    turtle.superpowers = true;
    turtle.name = `Super ${turtle.name.split(" ")[1]}`;
    return turtle;
}
let regularRaphael = {
    name: 'Powerless Raphael',
    superpowers: false
};
let superRaphael = mutateTurtle(regularRaphael);
console.log(regularRaphael); // -> ?
console.log(superRaphael); // -> ?

The above function does not adhere to 'pure function' conventions because it mutates an outside variable, 'regularRaphael'. The two console logs above will print the same object:

{name: "Super Raphael", superpowers: true}

We don't want to forget about regular Raphael entirely - I'm sure there are aspects of his pre-super life that are worth remembering. It is usually best to make a copy of the object or array you are modifying. Let's refactor the above code to make our function 'pure':

function mutateTurtle(turtle) {
    let superTurtle = JSON.parse(JSON.stringify(turtle));
    superTurtle.superpowers = true;
    superTurtle.name = `Super ${turtle.name.split(" ")[1]}`;
    return superTurtle;
}
let regularRaphael = {
    name: 'Powerless Raphael',
    superpowers: false
};
let superRaphael = mutateTurtle(regularRaphael);
console.log(regularRaphael); // -> ?
console.log(superRaphael); // -> ?

Here is what is printed this time:

{name: "Powerless Raphael", superpowers: false}
{name: "Super Raphael", superpowers: true}

We avoided mutating regularRaphael by making a copy of him. By first converting regularRaphael's object to a string, using 'JSON.stringify', then parsing that string back to a JSON object, using 'JSON.parse', we created an object with the same keys/values, but with a new memory location. This 'parse/stringify' trick should also work with nested arrays/objects.

Because our original 'regularRaphael' object did not contain deep nesting we also could have achieved our desired outcome by using the spread operator...

let superTurtle = {...turtle};

Or the 'Object.assign' method...

let superTurtle = Object.assign({}, turtle);

Now that I'm aware of how to make copies opposed to references, I'll leave the mutating to the turtles and fight to keep regular Raphael's memory alive.

Via GIPHY

Sources:

  1. Explaining Value vs. Reference in Javascript, by Arnav Aggarwal
  2. Different methods to copy an object in JavaScript, by Juned Lanja
  3. TMNT Cover Image

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (1)

Collapse
 
torianne02 profile image
Tori Crawford

This is a really informative article that is very entertaining to read. Great job Max!!

Teenage Mutant Ninja Turtles Laughing

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay