Query regarding declared function parameters and non-mutation

Tell us what’s happening:
Describe your issue in detail here.

I’m a little unsure of the definition below. Going to attempt to define it in my own terms. Please tell me if I’m off or on…
1. Declare function parameters - any computation inside a function depends only on the arguments passed to the function, and not on any global object or variable.
MY DEFINITION: In order to prevent data from being mutated, you place it into the function parameters. This means that it is out of the assignment game. You can assign it as a value to a new variable without it absorbing any change that the new variable undergoes.
Is this more or less it?

My other question is why this is the case? How does the original variable keep from being mutated if it’s possible to mutate if it is assigned to a new variable within the function.

  **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 (bookList, bookName) {
let newList = [...bookList]
newList.push(bookName);
return newList;

// Change code above this line
}

// Change code below this line
function remove (bookList, bookName) {
let newList = [...bookList];
const book_index = newList.indexOf(bookName);
if (book_index >= 0) {

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

  // Change code above this line
  }
}

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

console.log(bookList);
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36

Challenge: Refactor Global Variables Out of Functions

Link to the challenge:

In your solution, you aren’t assigning bookList to a new variable, you are making a new copy of it. Assigning it to a new variable would be something like:

let newList = bookList;

Since bookList is an array then newList is pointing to the same array and anything you do to newList you also do to bookList.

But in your code you are creating a new and distinct copy:

let newList = [...bookList];

newList is now its own array and you can do whatever you want to it without affect bookList.

Just to add function parameters can still mutate a global variable if it is a value passed by reference and not passed by value and your function changes it. Arrays and Objects being reference, which is why when you copy the shallow array of bookList with ... bookList is fine. But if you just mutate bookList without making a copy the global bookList would also be changed after the function. If it was a primitive value and you changed it, the global should still be the same. Someone please correct me if i am wrong.

example code here:

const dontMutate = [1,2,3,4,5,6,7,8,9];
const letsMutate = ['a','b','c','d','e','f','g','h','i'];
let myValue = 1;

console.log('dontMutate in the global scope '+dontMutate);
console.log('letsMutate in the global scope '+letsMutate);
console.log('myValue in the global scope '+myValue);

function mutator (parameter) {
  if (typeof(parameter) === 'number') {
    console.log('myValue before mutating '+parameter);
    parameter++;
    console.log('myValue not passed by reference '+parameter);
    return parameter;
  } else {
  console.log('mutator parameter before mutating ' +parameter);
  parameter[0] = 'z';
  console.log('the parameter after mutator function '+parameter);
  }
}

function doNotMutate (parameter) {
  console.log('parameter before doNotMutate function '+parameter);
  //lets make a copy so we dont mutate
  const copy = [...parameter];
  console.log('my copy '+copy);
  copy[0] = 10;
  console.log('the mutated copy '+copy);
  console.log('the parameter after doNotMutate mutates a copy '+parameter);
}

mutator(letsMutate);
doNotMutate(dontMutate);
mutator(myValue);

console.log('dontMutate global at the end '+dontMutate);
console.log('letsMutate global at the end '+letsMutate);
console.log('myValue global at the end '+myValue);
1 Like

The spread operator including the parameter as part of its value is a harmless copy and has no effect upon the actual state of it as an object.

This is an accurate statement?

If you are referring to this:

let newList = [...bookList];

Then yes, the spread operator is being used to create a copy of the bookList array and anything you do to newList will not affect bookList since they are now pointing to completely separate arrays.

1 Like