Arrays, mutations and refactoring

Tell us what’s happening:

So my code here works, but it took me a while to figure out and brings up a question about data types.

I had originally tried to just declare the variable newArr by assigning the value of bookList like so:

let newArr = bookList;

but working on the new array kept mutating the original array bookList. So I ended up creating a new empty array and then pushing each of the items from the original array into it as you can see below. It seemed like a bit of an excessive approach, but it also seemed necessary.

Am I right in thinking that this is because arrays are “reference” data types and not “primitive” – and what exactly does this mean? I thought I was only changing the new variable I had declared within the function, but that wasn’t what the test results said.

I’d greatly appreciate any clarification or pointers to helpful resources since I am still trying to wrap my head around these two basic types of data in Javascript.


Your code so far

// The global variable
var bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];

// Change code below this line
function add (currentBooks, bookName) {
 let newArr = [];
 currentBooks.forEach(book => newArr.push(book));
 return newArr;
 // Change code above this line

// Change code below this line
function remove (currentBooks, bookName) {
 let newArr = [];
 currentBooks.forEach(book => newArr.push(book));
 let book_index = newArr.indexOf(bookName);
 if (book_index >= 0) {

   newArr.splice(book_index, 1);
   return newArr;

   // Change code above this line

var newBookList = add(bookList, 'A Brief History of Time');
var newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
var newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');


Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36.

Challenge: Refactor Global Variables Out of Functions

Link to the challenge:

1 Like

When you have following code:

let a = 3;
let b = 3;
a === b; /* true */

a and b point to the same address in memory, that’s why line 3 gives you true. You can think of assignment operator as something that assigns address in memory. When you do following

let newArr = bookList;

you assign variable newArr to the address in memory of variable bookList. Primitive values are immutable, meaning you cannot go to that point in memory and change the value, you only can re-assign variable to the new address. Objects are mutable, meaning that you can change value at the address in memory different variable could point to.

1 Like

There are different ways of creating shallow clones and you’ve picked up not the easiest one :slight_smile:

const a = [1, 2, 3];
const b = [...a];
a === b; // false

const c = [1, 2, 3];
const d = c.slice();
c === d; // false

const e = [1, 2, 3];
const f = [];
Object.assign(f, e);
e === f; // false
1 Like

When arrays are copied, they are both pointing to the same piece of memory in the computer (called pointer I believe). Modify one, both are changed.

Primitive data types point to different pieces of memory even if you copy them.

let a=2, b=a

b is a new object in memory with value 2, no reference to a. Change b to 3 (b=3) and log a value (will be 2)

For just copying values (not cloning) of arrays use the spread operator:

let a1 = […a2]

Now and they are independent.

1 Like

What if a is the 100Mb text, how would you compare if a === b? :slight_smile:

@snigo, @anon10002461

Thanks so much for the replies! They help a lot.
And I knew there must be a simpler way than the forEach method I used!

  • George

you’re welcome. btw, ffox dev can be downloaded for linux from ff website

(shorter version of previous comment)

1 Like

Done! Thanks for the tip.