Avoid Mutations and Side Effects Using Functional: Is arguments protect the global variable ? Programming:

Hello,
I think I not really understand the sens of this two exercices.
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/functional-programming/avoid-mutations-and-side-effects-using-functional-programming
" Avoid Mutations and Side Effects Using Functional Programming"
And just after:
" Pass Arguments to Avoid External Dependence in a Function"

After my first reading, I said myself that the fact to put the global variable as argument protect the global variable of mutating. :thinking:

So I tried this two litle code in oder to verify if I well understand:

// The global variable
var fixedValue = 4;

function incrementer () {
  // Only change code below this line

return ++fixedValue

  // Only change code above this line
}
console.log(incrementer())   //  5
console.log(fixedValue)  //  5

Thus fixedValue is not protected.

// The global variable
var fixedValue = 4;

function incrementer (x) {
  // Only change code below this line

return ++x

  // Only change code above this line
}
console.log(incrementer(fixedValue))   //  5
console.log(fixedValue)  //  4

Thus super, fixedValue is protected.

Did I well understand the meaning of these exercises?

Can you explain why fixedValue is protected in your second example? If so then I think you have understood the point of these lessons.

because console.log(incrementer(fixedValue)) // 5
and

console.log(fixedValue)  //  4

fixedValue is still 4.

That doesn’t really answer why.


Parameters are just variables local to the function.

You are assigning the value of fixedValue to the x parameter variable and changing the value of it instead of changing fixedValue. The x parameter just contains a copy of the value.

This:

let globalVariable = 10;

function localScope(localVariable) {
  localVariable += 1;
  return localVariable;
}

console.log(localScope(globalVariable)); // 11
console.log(globalVariable); // 10

Is functionally the same as this:

let globalVariable = 10;

function localScope() {
  let localVariable = globalVariable;
  localVariable += 1;
  return localVariable;
}

console.log(localScope()); // 11
console.log(globalVariable); // 10

It doesn’t really protect the global it just doesn’t directly modify it. However, if the value being copied is of an object type you will still mutate it.

const globalVariable = [1, 2, 3, 4];

function localScope(localVariable) {
  localVariable[0] = 0;
}

localScope(globalVariable);
console.log(globalVariable); // [ 0, 2, 3, 4 ]
1 Like

If I well understand, the global variable doen’t change because put the variable as fonction’s parametre or in another local variable make a copy.

Plus as “the local variable takes precedence over the global variable.” it is normal that the global variable does not change:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/global-vs–local-scope-in-functions

Correct me if I m wrong…

it’s so the reason why we must make a copy of the arrays of books lists in this exercise:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions

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

/* This function should add a book to the list and return the list */
// New parameters should come before bookName

// Add your code below this line
function add(arr, bookName) {
  let newArr = [...arr]; // Copy the bookList array to a new array.
  newArr.push(bookName); // Add bookName parameter to the end of the new array.
  return newArr; // Return the new array.
}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

// Add your code below this line
function remove(arr, bookName) {
  let newArr = [...arr]; // Copy the bookList array to a new array.
  if (newArr.indexOf(bookName) >= 0) {
    // Check whether the bookName parameter is in new array.
    newArr.splice(newArr.indexOf(bookName), 1); // Remove the given paramater from the new array.
    return newArr; // Return the new array.
  }
}

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');

console.log(bookList);

Correct me if I m wrong…

  1. Because you are working with/on a different variable in a different scope.

I know the challenge uses the word “precedence” and I guess that is one way of thinking about it, but I also think it might potentially give the wrong impression. Precedence sounds like a priority system, but really it’s just first come first serve based on scopes. Edit: I guess first come first serve is a priority system, but it’s very simple and easy to understand. The word precedence in my mind makes it sound like something fancier might be going on.

The identifier (variable name) is resolved by starting from the closest scope to the usage and moving outwards/upwards. If it finds the identifier in an enclosing scope it stops looking and uses that identifier. There might be a hundred other variables named the same (hopefully not) living in scopes further out/up.

Imagine being on the ground floor of a building and looking for a person named John. You start at the first floor and start looking at the nameplates on each door then moving up one floor, and so on. If you find a flat with the name John you stop looking. There might be 10 more people named John living higher up in the building but you are just looking for the first one you find.

  1. Yes, because in that case, you are not getting a copy of a primitive value but a reference.

Thank you for your explanations.

Hello,
In order to verify I well understood again and following this article:

In the code below in regard to this exercise:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions

We don’t need to use “Object.assign()” to make copy of table because the copy is done inside a function ?

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

/* This function should add a book to the list and return the list */
// New parameters should come before bookName

// Add your code below this line
function add(arr, bookName) {
  let newArr = [...arr]; // Copy the bookList array to a new array.
  newArr.push(bookName); // Add bookName parameter to the end of the new array.
  return newArr; // Return the new array.
}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

// Add your code below this line
function remove(arr, bookName) {
  let newArr = [...arr]; // Copy the bookList array to a new array.
  if (newArr.indexOf(bookName) >= 0) {
    // Check whether the bookName parameter is in new array.
    newArr.splice(newArr.indexOf(bookName), 1); // Remove the given paramater from the new array.
    return newArr; // Return the new array.
  }
}

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');

console.log(bookList);


Edit: I may have misunderstood your question.

Are you referring to the array copy done using spread inside the functions? If so it doesn’t matter where you make the copy, at least not in regards to it being a copy, but it makes sense to do it at that location and at that time in the code execution.


No, passing an argument to a parameter is the same as a normal variable assignment. It does not create a copy.

Not sure what specifically in the code you posted you are referring to but it is using spread syntax to make copies of the array. The challenge you linked to is using an array, not an object Object.assign() is for objects.

Example code
const numbers = [1, 2, 3, 4, 5];

const notACopy = numbers;
notACopy[0] = 0;
console.log(numbers); // [ 0, 2, 3, 4, 5 ]

function mutating(notACopy) {
  notACopy[0] = 10;
}

mutating(numbers);
console.log(numbers); // [ 10, 2, 3, 4, 5 ]

const numbersCopy = [...numbers]
numbersCopy[0] = 1
console.log(numbersCopy); // [ 1, 2, 3, 4, 5 ]
console.log(numbers); // [ 10, 2, 3, 4, 5 ]