FAQ: Advanced Objects - Review

This community-built FAQ covers the “Review” exercise from the lesson “Advanced Objects”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Introduction To JavaScript

FAQs on the exercise Review

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Please, what is the solution to this Find the value of “this“ in a function inside of a method.

1 Like

this refers to the calling object, which value is that object. As I understand it, there is no way to find the name of the instance upon which the call is made.

Like yourself, I’m just as mystified by this question as you are. Hopefully somebody with more insight/wisdom will pipe in.

Something to consider, though I’m not sure this is what we’re after…

function listAllProperties(o) {
	var objectToInspect;     
	var result = [];
	
	for(objectToInspect = o; objectToInspect !== null; 
           objectToInspect = Object.getPrototypeOf(objectToInspect)) {  
        result = result.concat(
            Object.getOwnPropertyNames(objectToInspect)
        );  
    }
	
	return result; 
}
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

 > myCar = new Car('Toyota', 'Corolla', 2006)

 > listAllProperties(myCar)
<- (16) ["make", "model", "year", "constructor", "constructor", "__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "__proto__", "toLocaleString"]
 > myCar.valueOf()
<- Car {make: "Toyota", model: "Corolla", year: 2006}
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.getValues = function () {
    return this.valueOf();
  }
}
myCar = new Car('Toyota', 'Corolla', 2006)

 > myCar.getValues()
<- Car {make: "Toyota", model: "Corolla", year: 2006, getValues: ƒ}
2 Likes

Can you do a getter/setter in a factory function and how does it work when you pass in the arugments?

Cannot imagine why not. The return is an object proper, so everything is on the table. The returned object is what we define.

hello @mtf i want to ask you about something in this review ‘https://www.codecademy.com/paths/web-development/tracks/web-dev-js-arrays-loops-objects/modules/learn-javascript-objects/lessons/advanced-objects/exercises/review
How can i do that : Create a new factory function that can create object instances of your choice.
thanks,

It is kind of open-ended in the wording, but one interpretation might be that we can pass in the the key-value pairs of our own choosing, and have the function return an object with those properties.

function objectFactory(keysArray, valuesArray) {
   if (keysArray.length !== valuesArray.length) {
    return false;
  }
  returnObject = {};
  keysArray.forEach((x, i) => returnObject[x] = valuesArray[i]);
  return returnObject;
}

names = "Bob Mary Ted Alice Mike Carol".split(" ");
grades = [70, 80, 90, 85, 75, 65, 95];
results = objectFactory(names, grades);    // false
grades = [70, 80, 90, 85, 75, 65];
results = objectFactory(names, grades);
// {Alice: 85, Bob: 70, Carol: 65, Mary: 80, Mike: 75, Ted: 90}
1 Like

Thanks @mtf for your explication but i can’t understand what did you do here
keysArray.forEach((x, i) => returnObject = valuesArray[i]);

If the unit on iterators has not yet come up, then it won’t be familiar to you. Pardon me for jumping ahead, if that is the case.

Array.forEach() is a HIgh Order Function (one that takes a function as its argument) We can express the above in terms of a for loop…

returnObject = {}
for (let i = 0; i < keysArray.length; i++) {
    k = keysArray[i];
    v = valuesArray[k];
    returnObject[k] = v;
}
return returnObject;

The output will be the same as the earlier example.

Perhaps this is the answer?


I am using this keyword to call the value of the property firstName and age…

I have another question.

  1. In my code (https://gist.github.com/c23d681d29d1653fcc370f29ff1a6d69) I want to log the properties to the console of the object that is to be created by the factory function passengerList (if that makes sense?). But Object.keys(passengerList) returns an empty array.
    When I use it on one of the created passengers eg. Object.keys(pass1) it does return an array with the property keys.

Is it at all possible to log the property keys within the factory function to the console?

And 2: when I log the content of a passenger object to the console, it also shows the functions and get and set methods (eg age: [Getter], speak: [Function: speak]. Is there a way to exclude these from the log and only show the properties that contain only values such as string, integer and boolean without having to write an extra function to exclude these?

Since you have defined a backing variable, _gender then the setter and getter should use, this._gender.

Hi

Where can I find information about ‘this’ keyword use in Javascript, and why there is a conflict using it within objects when employing arrow function definitions? Thanks

Jaime Fernandez

Look for ‘Expressions and Operators’ on MDN.


{

}

denotes an execution context.

Now to add to the mystery,

((){

})()

denotes an immediately invoked function expression (as pseudo-code).

 > (function (value) {
     my_value = value 
   })('value')
<- undefined
 > my_value              //  global variable
<- "value"
 > window.my_value       //  window object property
<- "value"
 > this.my_value         //  execution context property
<- "value"

get _courses () {

return {appetizers:this.appetizers,  // Why must we put these returns inside curly braces??
                                                                       Why isnt the get _courses block sufficient?
       mains: this.mains,

       desserts: this.desserts,

Try and see what the console logs when you return without curly braces and what the type is. Your answer will lie there.

What’s the difference between these:

const artificialI = (name, age) => {
  name,
  age,
};

const artificialII = (name, age) => {
  return {
    name,
    age,
  }
};

The properties show up in different colours in the test enviroment, and I haven’t quite understood why yet.

Does your code run or is an error thrown? Perhaps you can share a screenshot.


As a preliminary refresher,

name =  "Jake";
age = 55;

const someObject = {
    name: name,
    age: age
}

console.log(someObject); 
// { name: 'Jake', age: 55 }

There is a shorthand notation for accomplishing the same as above.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#property_definitions

name =  "Jake";
age = 55;

const someObject = {
    name,
    age,
}

console.log(someObject); 
// { name: 'Jake', age: 55 }

With that out of the way, let’s look at your code snippets.

In your second snippet, you have an arrow function artificialII which has two parameters name and age. Since curly braces have been used for the body of the arrow function, therefore we need an explicit return if we wish to return something. In your code, an object will be returned which will have two properties. The values assigned to these properties will be provided by the arguments assigned to the parameters.

const artificialII = (name, age) => {
  return {
    name,
    age,
  }
};

console.log(artificialII("Jake", 55)); 
// { name: 'Jake', age: 55 }

Your first snippet will throw up a SyntaxError (unless you have made some mistake while copy pasting). That is because the curly braces after the the arrow will be interpreted as being the body of the arrow function and then name, age, won’t make sense. However if you do something like:

const artificialI = (name, age) => ({
  name,
  age,
});

console.log(artificialI("Jake", 55));
// { name: 'Jake', age: 55 }

then this will work and will be equivalent to the artificialII version.
After the arrow =>, the interpreter looks at whether there is a curly brace or not.
If there is a curly brace immediately after the arrow, then it is interpreted as being the body of the arrow function.
If there isn’t a curly brace, then it is interpreted as being a single expression whose value after evaluation will be implicitly returned. By using parentheses, we have chosen not to use curly braces for the body of the arrow function. The curly braces inside the parentheses will be interpreted as belonging to an object (and there will be no ambiguity that the braces aren’t meant to designate the body of the arrow function). This object will then be implicitly returned by the arrow function.

2 Likes

So essentially I confused functions and objects a bit when I made my code.
I was using object values in a function instead of using an object with values inside a function.

This makes more sense now, thank you.