Check my understanding // Output incorrect?


#1



Contact List Assignment


Hello again codecademy community! :slight_smile:

I was able to complete this assignment, but I'd like your help in explaining exactly what is happening with as little jargon as possible. I'd like a step-by-step description of the events/checking values/etc that is occuring in this program. Most especially the second for/in loop.

Can you check my understanding of the following? :

  1. First declaring new object named friends,

  2. Then giving two sub-objects named bill and steve.

  3. Then assigning properties of each sub-object: first name, last name, phone number, and address.

  4. Create a new function called list. It apparently takes in some parameter named records. But since there is not any records anywhere in the script, and the fact that records is never used in the function, it could be removed and just have function () { on the right hand side?

  5. The for loop checks for... whether or not the object "friends" has a key anywhere in it that is called "firstName". If there is, it prints out that firstName value. It was necessary to use the for loop because the firstName key is otherwise not a variable and cannot be referenced later in that function.

  6. The console prints out those firstNames that matched the criteria of belonging to the object friends.

  7. Once again another function is created, this time named "search". I have no idea why there's a "name" parameter that it is supposed to use in the function. There's no mention of name earlier in the script, so it cannot use any value for it?

  8. Within the search function, another for/in loop is created. This time it checks within the object "friends" for any key. I think the possibilities are "steve" and "bill". I don't know if it can access "bill.firstName" or not. I think no, but the next if loop makes it check those properties, so it doesn't have to yet..

  9. The if loop checks if the key belonging to object "friends" has a property named firstName that matches something... called name that was a parameter for the function. I dunno how this script knows what "name" is. This would make sense if instead of name, the code required firstName as a parameter to the function and in the equality checking. But nope, it's just "name"!
  10. At any rate, if the firstNames in the list match "name", then the function prints the key of the friends object that it came from, resulting in "bill" or "steve" printout (if successful).
  11. If firstNames != "name", then it'll print the message "No Match".

Note: Even though the code passed codecademy's check, it prints out

No Match
No Match
{"firstName":"Bill","lastName":"Blueberry","number":"(231) 142-2342","address":["113","Squidilean Road","Silicon Valley","CA"]}

instead of "Bill" and his information. Any explanation for that behaviour?

Thanks friends! :slight_smile:


var friends = new Object();
    friends.bill = new Object();
        friends.bill.firstName = "Bill";
        friends.bill.lastName = "Blueberry";
        friends.bill.number = "(231) 142-2342";
        friends.bill.address = ["113", "Squidilean Road", "Silicon Valley", "CA"];
    friends.steve = new Object();
        friends.steve.firstName = "Steve";
        friends.steve.lastName = "Soup";
        friends.steve.number = "(612) 202-9234";
        friends.steve.address = ["993", "Caribbean Cut", "Rochelle", "IL"];
        
 list = function (records) {
    for (var firstName in friends) {
        console.log(firstName);
        console.log(number);
    }
}

var search = function(name) {
    for (var key in friends) {
        if (friends[key].firstName === name) {
            //console.log(friends[key]);
            return friends[key];
        }
        else {
            console.log("No Match");
        }
    }
}

search("Bill");


17. this & methods // function parameter basics
#2

I'll go through your points one by one:

1-3: You are correct in these cases. An object (friends) is declared which itself contains two objects, Bill and Steve, with a bunch of properties.

4: You are correct that a function called list is declared. However, where you are getting confused is the argument it takes. When declaring a function, the argument is just a placeholder name - you could call it records, userList, or giantBananas but it wouldn't make a difference to how it functions (so long as the argument name is the same throughout the function declaration).

When you call the function (e.g. list(friends)), whatever you pass in as the argument is temporarily treated as if it was called records.

5-6: When you type 'var firstName', you're not actually referencing the firstName from your friends object. You're creating a temporary variable which is only available inside the for loop. The value that is populating firstName in this case is actually each of the objects inside friends: Bill and Steve.

If you actually called your function (e.g. list(friends)), you'd receive an error because 'number' is not defined. If you want to access an object's properties, you could do it like so:

for (var person in friends) {
    console.log(friends[person].firstName);
    console.log(friends[person].number);
}

Note that I've changed the wording in the for loop from 'firstName' to 'person' to highlight that it is indeed a temporary value. In this case, the loop would run, substitute person with the objects 'Bill' and then 'Steve' and print their first names and numbers.

7-11: Again, the argument name is a temporary reference when declaring the function. In the loop, for each value (i.e. the objects Bill and Steve) in the friends object, the firstName of that value is compared to whatever you pass into the search function.

So if you call search("Bill"), the variable name in this case will be "Bill".

If it finds a match, it should log that name to the console (but doesn't because that line is commented out), then it returns the object. If not, the string "No match" is logged to the console.


Looking at your output, the reason "No match" is printed twice is possibly because the lesson is testing your code by searching for a couple of random names (I haven't checked this).

The console will also always display the return value of a function - in this case when you called search("Bill"), the entire Bill object is returned. The reason it doesn't look pretty is because it's in its native format (also known as object literal). If you wanted it to look nice you'd have to write another loop which individually prints out the values from each of the properties of the object.


So you have some confusion as to how referencing and variables work in JavaScript objects/functions, but I hope this helps!

I would also highly recommend looking into writing your objects in the object literal notation.


#3

Wow, @nedwards! That is amazing. Thank you so very much for taking the time out of your day to go through this step by step. I think you did an excellent job at explaining each part of this and I think that as long as I keep practising, I could get to the point where I understand this more intuitively!

I did have confusion, especially with the "placeholder" idea. I didn't know that was how it worked. I'm going to have to do some practising before I truly feel comfortable with where I must declare a variable vs. use a placeholder. Seems simple, but I don't want to trust my competency pre-maturely. :wink:

Is there a benefit to the object literal notation that you could explain? It is just a little less intuitive to me right now.

Thanks again! Helped tons! I think anyone stuck on this step of the contact list assignment would benefit from reading your walkthrough.


#4

No problem! Once you've got your head around how arguments and parameters work in functions it'll be a lot easier to understand them as a whole.

A simple demonstration is something like this:

var string1 = "foo";
var string2 = "bar";

var myFunction = function(myString) {
    console.log("The value of myString is: " + myString);
}

myFunction(string1); // The value of myString is foo
myFunction(string2); // The value of myString is bar

Why you should use object literal notation when declaring objects?

Firstly, there's a slight advantage in terms of code organisation. Consider the two examples below:

Object constructor syntax:

var person = new Object();
person.firstName = "Fred";
person.lastName = "Jones";

Object literal notation:

var person = {
    firstName: "Fred",
    lastName: "Jones"
};

In the constructor example, you're making multiple function calls to both create the object and assign its properties.

With object literal notation, however, the creation of the object and its properties is done in only one call. There are fewer characters used without the repetition (Don't Repeat Yourself (DIY) is important to remember) and thus the code looks cleaner in general.

Finally, object literals are the accepted convention. If you code falls more into line with other people's code, you will find it both easier and quicker to read (and find errors).


#5

@nedwards, Thank you again for taking out so much time and writing a comprehensive answer! :smiley:

I think I understand functions for now... until something more nuanced confuses me, I'm sure. lol.

I wasn't aware object literal was practically common convention. I did google previously the differences and why to use one form over another, but just received pages that said "it depends on what you're doing" and then provided extremely complex and niche examples of why one might be better than the other. :stuck_out_tongue:

I think I was using the constructor notation simply because it made it obvious to me (a learner), that I was dealing with an object. Now that I've been on object lessons for a while longer, I am more familiar with literal notation to the point where I can probably go "Aha, that's an object, not just a function that's missing the 'function()' part of the coding and is using ',' instead of ';' for some reason." I feel much more confident now, and you've helped a lot in my learning.

Your advice is invaluable.

-SM


#6

I'm glad to hear! There are probably some niche situations where the constructor is required. In fact, what you may have come across is dealing with prototyping (the concept that all objects inherit some properties from another prototype object above).

This will probably crop up in the lessons to come, but as a quick overview:


Say you want to create multiple objects representing people. You could use the object literal notation as above, but this can be tedious if you want to create multiple people with the same property names.

In this case, it'd be easier if we could just create a single constructor (or object prototype) from which new objects of that type can automatically inherit the properties "firstName", "lastName" etc without us having to type it all out!

How we do this is use the object constructor function:

function Person(first, last, email) {
    this.firstName = first;
    this.lastName = last;
    this.email = email;
}

'this' is a special keyword which refers to the current object in question. It's like saying "Make this object's firstName set to the value of first".

Now, with this prototype, we can now easily create new people like so:

var bob = new Person("Bob", "McFred", "bobmcfred@email.com");
var jim = new Person("Jim", "McBill", "jimmcbill@email.com");

Much quicker!

I hope this gives you a little booster for understanding the further complex (but important) methods of object construction.


#7

Good timing @nedwards, as I'm currently on that lesson. I'm understanding and catching on pretty well. However, I have one (probably) simple question.

I completed the PHP course, and encountered classes, which was pretty intuitive. Is a prototype pretty much equivalent to a class? Or is there a difference?

In the JavaScript course, it mentions prototypes, but then it also mentions classes, so I get confused. Also, it seems to jump around and teach the same thing a few times (apparently not as a review?) in the Intro to Objects II lesson. But I guess that just gives me more opportunity to reapproach ideas with a new mindset. ^^

Thanks again! :smiley:


Edit : So, as I'm learning it seems the "prototype" refers to the collection of properties within a parent object type (which the lesson is calling a class). I can just keep going and see if I figure it out. If not, then I'll ask for help. Sorry for the early questioning. Haha. ^^;


#8

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.