FAQ: Advanced Objects - Factory Functions

This community-built FAQ covers the “Factory Functions” 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 Factory Functions

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!

I think i’m missing the point of this exercise. I have it all working :

// step 1
const robotFactory = (model, mobile) => {
  return {
    model: 'model',
    mobile: 'mobile',
    beep() {
    	console.log('Beep Boop');
  	}
  }
};
// step 2
const tinCan = robotFactory('P-500', true);

// step 3
tinCan.beep();

The results spits out “Beep Boop”. My question is : Where are the (P-500, true) values from step 2.? What was I supposed to learn from this?

1 Like

I also don’t get what that “true” of the second argument in “step 2” is for.
I changed to “false” to test out, and tinCan.beep(); still works.

If you poll their values, they will be found…

console.log(tinCan.model, tinCan.mobile, tinCan.beep());
3 Likes

Hey, in this exercise it is asked of us to use const to declare the monster function, and i tried to use function out of curiosity, and it’s working.
Hence my question : is there any reason to use either one rather than the other ?

1 Like

Concerning the lesson (not the exercise), what happens to the “catchPhrase” parameter to “monsterFactory”?

catchPhrase is not a property of the monster object, but there seems to be a copy maintained somewhere because you can create two monster objects with different catchPhrases and the scare() method works as expected.

Thanks for any explanation you can supply!

When I attempt to use an old-fashioned function declaration to create a factory function, I’m able to complete the assignment so that all the checkboxes pass in the Codecademy exercise. However, after the console prints “Beep Boop,” it also creates a new line that returns “undefined.”

Is it improper to create an object in this manner? Is there something else that I have included or excluded that is causing this extra line to print? Please see below for the code I used to complete the assignment:

function robotFactory(model, mobile) {
  return {
    model: model, 
    mobile: mobile,
    beep() {console.log("Beep Boop\n")}
  }
}

const tinCan = robotFactory('P-500', true);

console.log(tinCan.beep());

The method is logging, so when you log it again you get the return from console.log() which is undefined. Lesson here, log once. Call the method without logging.

tincan.beep()
3 Likes

That makes perfect sense. Thanks, Roy!

1 Like

That did not answer my question. Regardless of what kind of object it is, why does catchPhrase persist? Knowing a little more about JS now, I would say it persists because it’s in a closure. In this case, catchPhrase acts like a property of the created object.

Thanks,

Ken

Would this code be any good? (Not for the exercise, just for knowledge)

let monsterFactory = (model, mobile){
return name = {
model: model
mobile: mobile
beep(){
console.log("Beep Boop");
}
}
}

I think it would be just better to assign an object directly from the factory function. This code may seem stupid and wrong, but I’m here to find out if it is.

We cannot make an assignment in a return statement.

Be aware of the syntax of plain objects… Comma separated properties.

Ditto what @mtf said, and you can declare a function either with the function key word or with let, const, var and the arrow syntax. Unless you are planning to change the properties of your ‘monsters’ dynamically with code later in your program, I would use const to declare the function, or just use the function key word.
Either:

function monsterFactory(model, mobile) {
  // function body to 'return' a monster object
}

Or:

const monsterFactory = (model, mobile) => {
  // function body to 'return' a monster object
}

Why does the key and its value have the same name ?

If you mean this,

model: model,
mobile: mobile,

it is just for simplicity. The key is the attribute name, the value is the parameter of the constructor. Params can be given any name, but it is common to see it given the same name as the property to which it is assigned.

But what is the benefit of declaring the factory function with const rather than function? Are there different use cases for each? Thanks.

It basically is just saying that each robot object created by the factory function will have a model number. Remember that the key/value pairs in an object are stored like this - KEY: VALUE. So a model number will be stored like this - MODEL_KEY: MODEL_VALUE.

We are using the word ‘model’ as the name for both the key and for the value because this is the most simple and accurate way to identify what each one is - just like referring to a dog as a dog in conversation, or a cat as a cat. The fact that they are arranged in a KEY: VALUE format, with a colon and within an object structure formed by {}, means that Javascript will not confuse them for each other. You could theoretically use any word when declaring the factory function, as long as you’re consistent. For example:

function robotFactory (MODEL_VALUE, MOBILE_VALUE) {
  return {
    model: MODEL_VALUE,
    mobile: MOBILE_VALUE,
    beep() {
      console.log('Beep Boop');
    }
  }
}

Hope this helps you to see the pattern.
(Edited a few times for clarity and formatting)

Hello, @upquark00. Welcome to the forum!
I added a couple of comments to the example from your post demonstrating one reason you may want to assign your function to a variable declared with const.

Using standard function declaration:

function robotFactory (MODEL_VALUE, MOBILE_VALUE) {
  return {
    model: MODEL_VALUE,
    mobile: MOBILE_VALUE,
    beep() {
      console.log('Beep Boop');
    }
  }
}

const robot = robotFactory(100101, false)
robot.beep() //prints 'Beep Boop'

robotFactory = 5 //reassigned the function to a simple int by 'mistake'
console.log(robotFactory) //prints 5

const robot2 = robotFactory(100102, true) //throws: TypeError: robotFactory is not a function
robot2.beep() 

Using the arrow function syntax declared with const:

const robotFactory = (MODEL_VALUE, MOBILE_VALUE) => {
  return {
    model: MODEL_VALUE,
    mobile: MOBILE_VALUE,
    beep() {
      console.log('Beep Boop');
    }
  }
}

const robot = robotFactory(100101, false)
robot.beep() //prints 'Beep Boop'

robotFactory = 5 //throws: TypeError: Assignment to constant variable

//these 2 lines won't be executed until we fix the error above
const robot2 = robotFactory(100102, true)
robot2.beep()

Using the arrow syntax with const offers some protection of the function by not allowing the function name to be unintentionally re-assigned to some other value.

2 Likes

That’s very interesting! Thank you so much for sharing. I’m not sure if this would be terribly difficult to explain, but if it’s not - why does the arrow version throw this TypeError, while the standard declaration does not?

Please give us an example where the error is thrown.