Object Alteration

Hi every one,

I’m working on FFC’s Functional Programming Lessons and I’ve encountered myself with something I really can’t explain, I’ll share the code and I’ll describe it: the thing that’s bothering me is located within the add function(), more precisely in the console.log() statements:

// global variable
var bookList = ["Book1", "Book2", "Book3", "Book4"];

/* This function should add a book to the list and return the list */

function add (bookList1, bookName) {
  console.log(`Before push ${bookList1}`); // Returns ["Book1", "Book2", "Book3", "Book4"]
  let newArray = bookList1;
  newArray.push(bookName);
  console.log(`After push ${bookList1}`); // Should return the same, but returns a modified array with Book5
  return newArray;
}



var newBookList = add(bookList, 'Book5');

console.log(bookList);

Shouldn’t console.log(bookList1) before newArray.push() and console.log(bookList1) after newArray.push() return the same exact value? Why is bookList1 been altered? I really can’t find an answer to it.

Thank you very much in advance for your time and help guys, appreciate it!

Hello Togeri.

Immutability is something most programmers have to frequently deal with. I could try to explain it, but this blog post has everything you are looking for + more:
Immutable JavaScript
Specifically, the bit on arrays. It has your exact example:

Arrays

Let’s do a little example of how you could add an item to an array in a mutating way:

const characters = [ 'Obi-Wan', 'Vader' ]
const newCharacters = characters

newCharacters.push('Luke')

console.log(characters === newCharacters) // true :-(

The same problem as with objects. We’re desperately failing in creating a new array, we just mutated the old one. Gladly ES6 contains a spread operator for array’s! This feature is even already in the final version of ES6. Here’s how to use it:

const characters = [ 'Obi-Wan', 'Vader' ]
const newCharacters = [ ...characters, 'Luke' ]

console.log(characters === newCharacters) // false
console.log(characters) // [ 'Obi-Wan', 'Vader' ]
console.log(newCharacters) // [ 'Obi-Wan', 'Vader', 'Luke' ]

Nice, that was easy! We created a new array containing the old characters plus ‘Luke’, leaving the old array intact.

So, give it a read. It will help your understanding, as well as provide a solution.

Hope this helps

2 Likes

Hi @Sky020 , thanks for the solution!!

This is very well explained and the article has helped me wrap my mind around mutability, and the situations where JS pass parameters by value vs by reference (AKA Objects, thus including arrays).

Thank you very much for taking your time answering this doubt! Also, the way I worked myself around was with the array.slice() method, which creates a copy without modifying the array, but your solutions is much cleaner!

Answer marked as solution !

On this line you make bookList1 pointing to the same point in computer memory as newArray. So when you type either newArray or bookList1 it brings you to the same thing, think of it like buying 2 different domains and pointing them to the same IP (website), now what’s gonna happen if you alter that website in some way?

2 Likes

About the article… :man_facepalming:
It has very little to do with immutability. Just think about what the author is suggesting. So to keep Ironman immutable, I just must not use it and put his clone in every fight he’s about to encounter, right? It would probably work, but don’t you find this kind of immutability wacky?

AND, the cloning way he suggested would not save Ironman, I’m afraid. Check this out:

const immutableMarvelUniverse = {
  houseOfTonyStark: {
    hero: 'Ironman'
  }
};

const safeClone = { ...immutableMarvelUniverse };

safeClone.houseOfTonyStark.hero += ' is dead!';

console.log(immutableMarvelUniverse);
1 Like

You are right about that…I will need to do some more research on this. Thank you, for pointing this out.

1 Like