Why does this Work? It Shouldn't - Functional Programming - Refactor Global Variables Out of Functions

Tell us what’s happening:
Hi everyone

So, this is my solution for this functional programming argument. I have used slice() in my function to create a copy of the global array, and then I do the add/ remove operations on it and return it.

It works and passed the tests, importantly, the test that requires that the global array not be changed. The thing is - as far as I understand it, it shouldn’t work.

According to this guide, slice() returns a shallow copy of the array - that is, a different object but with references to the very same elements the original array contains. That is, writing

let myBooks = orgBooksArr.slice(); 

Should result in a differnet array object but that contains references (pointers?) to the same elements as in orgBooksArr, so that changing the copy array should lead to a change in the original array, shouldn’t it?

  **Your code so far**
// The global variable
const 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(collection, bookName) {
let myBooks = collection.slice(); 
myBooks.push(bookName);
return myBooks;

// Change code above this line
}

// Change code below this line
function remove(collection, bookName) {
let myBooks = collection.slice(); 
const book_index = myBooks.indexOf(bookName);
if (book_index >= 0) {

  myBooks.splice(book_index, 1);

  return myBooks;

// Change code above this line
  }
}

add(bookList, "yes");
remove(bookList, "On The Electrodynamics of Moving Bodies") 
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0

Challenge: Functional Programming - Refactor Global Variables Out of Functions

Link to the challenge:

Read some more on mutable and immutable functions

Ok, so while writing this message I think I figured it out. Please let me know if I have this correctly:

A change to a shallow-copy array object is not the same as a change to the elements that are inside the shallow-copy array. That is, changing the shallow-copy array object is only that - a change to the array object. The elements that the array contains are left untouched.

Even if an element is added or removed from the shallow-copy array object, the same original elements that are in the original array are not changed. The original array still has its own original references to its original elements. The shallow-copy array object just “organizes” the elements differently, but it doesn’t actually touch them.

Does this make sense?
(leaving this here in the forum, perhaps it would help someone else in the future).

Thanks for the comment. I haven’t seen this term in the context of functions (only objects - which I come to realize, include functions).

Functions execute your code, so it sends received information and brings back information based on what it done with it before sending it back.

When talking about it being a shallow copy it just means that it will only work on one dimensional objects, a simple array like [1,2,3,4,5] for example. But if it was multidimensional like [1,2,[3],4,5] the array holding 3 is its own object. It is not getting fully copied, only the memory address is being copied. So if you changed the number 3 in that array, it would effect the original version as well as your shallow copy.

const something = [1,2,[3],4,5]
const somethingElse = something.slice()

console.log('something:',something, 'somethingElse',somethingElse) //something: [ 1, 2, [ 3 ], 4, 5 ] somethingElse [ 1, 2, [ 3 ], 4, 5 ]
somethingElse[2][0] = 7
somethingElse[1] = 7
console.log('something:',something, 'somethingElse',somethingElse)//something: [ 1, 2, [ 7 ], 4, 5 ] somethingElse [ 1, 7, [ 7 ], 4, 5 ]

So how is somethingElse the value of 7 if you accessed the 2nd item(ignoring zero based indexing for demonstration)? is it cause you count up until before the item you want to modify?

Because the 2 at index 1 was in the “shallow” end of the pool. Those values in somethingElse are not the same as the ones in something. So when i changed that in somethingElse, something was unaffected. They are a copy because of the slice grabbing all the elements in that array then returning a new array to somethingElse. 3 was in the “deep” end of the pool. When i modified that it changed across both versions because even tho now something and somethingElse are different arrays, that element, the array at index 2 is the same for both something and somethingElse, pointing to the same address. So changing a value in that array will be reflected across every version if its just a shallow copy.

Watch it run and pay attention to where the arrows are pointing.

1 Like

JavaScript always copies, and here you are making a copy of the array contents (in this case strings). The values in the array are primitives. A primitive is the actual value, so if there’s a copy that makes two, they can’t live in the same place in memory.

1 Like

The way I am reading it is, he accessed the second primitive within the array nr 0 then set it equal to 7. Then he accessed the 1st array and give the 2nd primitive within that array that value?