Refactor Global Variables Out of Functions - help

Tell us what’s happening:

I have two quick questions… hope someone can help me understand.

  1. Am I correct in assuming that you cannot simply manipulate an argument passed inside a function? So, for example:
function add (arr, bookName) {
arr.splice(1, 1);
}

That won’t work? Do you have to assign a variable to arr before manipulating that variable?

function add (arr, bookName) {
let newArr = [...arr];
newArr.splice(1, 1);
}
  1. In this example below, what is the difference between returning the variable newList after pushing a new value into the array, or doing it all in one line? Why does doing it all in one line not work?
function add (arr, bookName) {
    let newList = [...arr];
    newList.push(bookName);
    return newList;
}

vs.

function add (arr, bookName) {
    let newList = [...arr];
    return newList.push(bookName);
}

Finally, it looks like I need to understand how arguments work a bit better. Can someone point me to a resource somewhere to read up more on the fundamentals of how arguments work, what I can and cannot do with them, etc.?

Thank you!

Sidney

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions

  1. manipulating an argument inside a function is totally fine (it’s exactly the same as having a variables called arr and bookName, they’re just values, you can do whatever you want to them), but in this case it won’t do for two reasons:

    function add (arr, bookName) {
      arr.splice(1, 1);
    }
    
    • splice mutates an array, and the instructions explicitly say do not do that.
    • you’re not returning anything from this function, and if you did return what you have, splice returns the deleted (removed) elements, not the array they are removed from.
  2. push has exactly the same problem as splice: it mutates the original array, and the task explicitly says do not do that. And again, push does not return the array, it returns the new length of the array, so you would be returning a number.

So yes, in this case, you can copy the array, make changes to the copy, then return the copy.

This isn’t really to do with arguments though, it seems to be more that you’re unaware of what these array methods do - I’d strongly advise using console.log() to see what is happening, and reading the documentation on the functions, in particular what the return values are -

1 Like

You can manipulate function parameters inside the function, HOWEVER. HUGE CAVEAT. For non-primitive objects like arrays the parameter is a reference to the original array’s data, meaning changes you make to them inside the function will alter the array outside of the function! This can get you into huge trouble if you aren’t aware of it. It’s much safer to build a new array and return it than to mutate data being passed in.

1 Like

Thank you! I know about the missing return (I didn’t copy my entire code). But I am trying to understand when I push onto the newly created array newArr, does it also affect the original argument, arr because they point to the same object.

To ensure that I do not alter the original array, is it enough to declare:
newArr = []; and then point it to the argument newArr = arr;?

Or should I slice it to make sure I am not altering the original array:

newArr = arr.slice();

Thank you!

To not affect the original array you need to create a copy, with the spread operator, slice or concat

1 Like

Yes, this is what I mean when I say it mutates the array. All of these methods alter arrays:

No, because all you’re doing with that is saying that newArr points at exactly the same thing as arr

Objects (of which arrays are a type of) are collections of values. When you say arr = [1,2,3], that 1, 2, and 3 aren’t all stored together. You’re just saying arr points at a thing that knows where those values are stored (a reference). arr is not the values 1, 2, and 3.

If you want a new version, a copy, then yes you would is something that creates a new array based on the original - arr.slice(), [...arr] etc