Refactor Global Variables Out of Functions-WuTangStyle

Tell us what’s happening:

Salve, mundi!

I’m new to FCC and even newer to the forum - forgive me if anything I post is overly basic!

Spent hours working on this problem and have finally produced a solution. I have two intents w/ this post…the first is to give a simple solution for beginners that actually works (traversed many forum posts, wasnt able to find one that worked+made sense to me as a beginner).

My second intent is to inquire about the difference between “let” and “var”, both in this challenge and in general.
My current understanding is that ‘let’ is for declaring variables in a limited block or scope while ‘var’ makes global variables or local to an entire function. So my question is why I had to change ‘let’ to ‘var’ within my remove function to make the code run. If ‘let’ is declared within a function is it not global to the function…?

Thanks for any input!

TL;DR: 1. heres a working solution
2. what’s the practical difference between let and var within a function?

Your code so far


function add (john, bookName) {
  var john = [...bookList];
  john.push(bookName);
  return john;
  // Add your code above this line
}

function remove (bookList, bookName) {
  if (bookList.indexOf(bookName) >= 0) {
    **var** john = [...bookList];
    **var** elyse = john.indexOf(bookName);
    john.splice(elyse, 1)
    return john;

    
    // Add your code above this line
    }
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36.

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

The exercise was to avoid using bookList as a global variable accessed within the functions. Your add function fails in this regard:

function add (john, bookName) {
  var john = [...**bookList**];
  john.push(bookName);
  return john;
  // Add your code above this line
}

It should be

function add (bookList, bookName) {
  var john = [...bookList];
  john.push(bookName);
  return john;
  // Add your code above this line
}

As far as var versus let here…

var declarations are processed before any code is executed, so I’d say that for “var john” that the function argument of “john” is being handed to a variable in the local scope named john already defined, so you won’t get an error in that case (i.e., it works).

Using a let will end up with the function trying to declare john after the function argument is passed in, so you get a duplicate declaration error when the function is run. (You can see this in the console.)

Your remove function actually works with let.

References for let and var:

var

let

Hope this helps…

First things first; your post on let vs var made more sense than anything I’ve seen so far, Tiger Style!

I have a follow up question of sorts, though…(last one for today, promise!) I understand that the purpose of the exercise is to avoid accessing global variables within functions. So does that mean that by putting a global variable as a parameter for a function it (the global var) doesn’t have to be re-called/copied within said function and still will not be altered on a global scale? I know that I’m closely restating the purpose of the exercise with my question but when I look at it from varying levels of complexity it makes sense on some levels and doesn’t on others…Suppose i’m looking for the practical difference between what I did on my add function and the right way of doing it (your way) and why I would use one way over another?

No worries :slight_smile:

Ideally, a function shouldn’t know anything about objects outside of its own scope. If it directly refer to values outside that scope, you run the risk of side effects that may not be documented.

More specifically, in JavaScript , objects used as parameters to functions are passed in by reference, not value (i.e., not a copy of the object), so handing the bookList to the add function and doing something directly with it would actually change its value. For example,

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

function add1(bookList, bookName) {
  bookList.push(bookName);
  return bookList;
}

function add2(bookList, bookName) {
 let john = [...bookList];
 john.push(bookName);
 return john;
}

Using the add function, you’d see that “A Brief History of Time” had been added to bookList. The add2 function creates a copy of bookList and assigns that to john, so using the add2 function would not change bookList.

Hopefully, this helps and is not overly long and rambling.

1 Like

My apologies, won’t happen again!