Make a Person project

First of all, here is a link to CodePen with some code.
It includes the test cases in this project set up as functions for testing.
I will be referring to it in the forum post content. It should be pretty easy to figure out for anyone who has reached the “Make a Person project” on Free Code Camp.

You can close the CSS window in Code Pen from the start.
You can probably close the HTML code list window after reading it.

Note: The code in the solution in CodePen is not mine. I found it online. It works. It solves the project. I am NOT going to use it to for my list of projects.
I am using it as an example to try to figure out how things work and to try to understand what the project is trying to teach so I can write my own solution.

I did write a couple of pages of code with some solutions to some of the test cases. But, I couldn’t get all of them to work. Then, I found the solution code online and figured that I should post something to the forums to try to get some direction. (Yeah - I don’t have those other solutions that I wrote. But, I was getting the first and last names from the input and putting it into an array, then getting the 0 and 1 indexes, etc. I just couldn’t get everything to work.)

I am at a point where I am really stumped about getting the whole solution to all the test cases. And, I don’t even know where to start asking questions. So, I figured I’d throw up all of this in a forum post to get some help about how to better understand the concepts behind this project.

I understand JavaScript objects. (name-value pairs, etc.)
I understand how to use a constructor to create multiple objects with the same object properties, object methods and functions by going through the MDN pages like this one to create Car objects:


There is a section on this web page for adding methods to an object. But, it seems to be a bit different from what is going on in the “Make a Person” project…or else, I am not seeing the connection.

I read the pages linked in the Hints for “Closures” and “Details of the Object Model”. But, they didn’t give me much to go on for this project which is why I am posting this. I feel like I need another MDN page to bridge between the Working with Objects MDN page that I linked above, and these two MDN pages in the hints. I feel like I understand a lot of it. I just don’t see how it connects to the “Make a Person” project. Are there other websites or other pages on MDN that I can try reading to understand this project’s goals?

I have completed all the Free Code Camp projects up to this point in order. Are there projects I could look at again before doing this one so I could get a better starting point for this one?

Here are some specific questions I have about the code solution in Code Pen. Maybe they will help give some idea about what I am confused about and what I need to learn/read up on/practice:

See the Code Pen code:

Why do bob04 and bob05 in my CodePen code return undefined? Didn’t the code just after “/***** functions for testing *****/” create a new Person object named “bob” with a first and last name when the page is loaded?
I don’t understand what is going on. The functions bob06 and bob07 return the first and last name.

I do understand what is going on in the second set of functions from bob09 onward about setting new values.

Note: There didn’t seem to be a Wiki page for this.

What we’re doing is known as encapsulation, or sometimes just code-hiding. The way we’re doing this is via closures. With any person object, what we want is to only be able to access the object properties via accessor methods, in this case .getFirstName() and .getLastName(). Here’s (basically) what’s happening:

  • The Person object is called with the new keyword. Person is, in fact, a normal function, and the new keyword does some behind-the-scenes magic with prototype linkage that we don’t need to worry about right now.

  • Because the properties .firstName and .lastName are a part of the function call that is the Person object, they are local to that scope. This means you cannot access them directly. If you’ve heard about using something like window.onload = function(){... to “keep the global scope clean”, or something like that, this is the very same thing.

  • All of the functions attached to the object via this has access to the Person function’s scope, so when you call bob.getFirstName(), the logic inside of that function is able to get the information you need.

You should know that this is widely regarded as one of the most difficult concepts to fully grasp in JavaScript. You may understand it in one context only to have it bite you in the ass in another, perhaps looking totally unfamiliar and strange. You might have it down one day, then wake up feeling like you forgot it all. You will most certainly write bugs that are directly related to lexical scope and will be easily solved with a simple closure, which you will understand after 3 days of debugging. I still find myself having to review this concept now and again. With all that said, you should be able to grasp this particular code challenge if you watch this video by one of my favorite YouTubers, LearnCode.academy. Don’t stress out over it too much, because a part of being able to understand scope and access is just a matter of experience. You will get it.

8 Likes

Thanks a million for this explanation. I will read it again and watch the video

I do understand scope to some extent. I didn’t know that was what was happening here. And, I have read so many web pages lately I probably missed it somewhere due to overload and frustration.

In a nutshell, if I am understanding what you are saying this is what is happening:

Accessing bob.firstName and bob.lastName can be done inside the function. That is why the bob04() and bob05() functions in my Code Pen code return undefined.

But, outside the function, the code has to use the methods as in bob06() and bob07()

<p onclick="bob04();">bob.firstName should return undefined.</p >
<p onclick="bob05();">bob.lastName should return undefined.</p >
<p onclick="bob06();">bob.getFirstName() should return "Bob".</p >
<p onclick="bob07();">bob.getLastName() should return "Ross".</p >

As a side note: I have been reading about global variables in JS. I recently used one in a FCC project and wondered about whether or not it was a good idea to do so, or put functions within functions. From what I’ve read, functions within functions is better.
https://www.w3.org/wiki/JavaScript_best_practices

Yes, exactly. Conceptually scope is not that difficult, but it gets into so many nooks and crannies, taking such odd shapes that it’s unrecognizable in some contexts.

Yup! More to the point, it can only be accessed from inside the function. Pat yourself on the back, you’ve got this.

Absolutely avoid them. It’s fine for these small, self contained challenges like Make a Person, but in a project you don’t want a variable name you write to conflict with another variable of the same name in a library. You’ll be utilizing the concepts in this challenge for the rest of your career so that you can effectively hide data and only expose the functionality you want.

Thanks, again, for the reply and encouragement.

And, thanks for the video recommendation. I watched the first video and bookmarked a lot of the other ones listed on the YouTube page. Lots to explore.

These comments have been very helpful.

@PortableStick, I’ve been working through this challenge, and haven’t yet come up with the solution. Am I on the right track in considering the module patten as a way to think about writing the function?

Absolutely. :thumbsup: :star:

1 Like

@PortableStick, so I solved it, finally! Thank you for pointing me in the right direction. I’m still not 100% sure though about what’s happening behind the scenes, specifically in regards to the following:

var bob = new Person('Bob Ross'); // full name is **Bob Ross**
bob.setFirstName("Haskell"); // first name is changed to **Haskell**
bob.getFullName(); // full name is now **Haskell Ross**

How is it that getFullName “knows” or “remembers” that setFirstName was called and assigned a new value to firstName?

Is it because all these methods, being closures, share the same referencing environment? So that if a var like firstName is set a new value after setFirstName is called, then a get method will know about the re-assignment? Because the environment has changed accordingly?

I feel like I’m hovering, just hovering over the reason, but not quite there :P. Thank you.

More accurately: functions have access to variables in their enclosing scope.

function giveDoctorate(name) {
    var name = name;
    var doctorPerson = {};
    doctorPerson.getTitle = function() {
        var title = "Dr. ";
        return title + name; // has access to the variable 'name'
    }
    doctorPerson.changeProfession = function() {
        console.log(title); //this would error out because it doesn't have access to the adjacent function's scope
        return "Space Emperor " + name;
    }
}
2 Likes