2

I'm pretty new to JS and I'm trying to wrap my head around the object topic in JS. What I'm trying to do is to set a property of an object prototype to an uninitialized array, so that I can later add multiple objects to that array (for instances of the prototype object) My code looks like this so far:

function cocktail(){
this.prototype.ingredients = [];
this.printIngredients = function() {
 var i;
 for (i = 0; i<this.ingredients.length; ++i) {
 console.log(this.ingredients.fluid);
 console.log(this.ingredients.amount);
 }
 }
}
var Mojito = new cocktail();
Mojito.ingredients.push({"fluid":"White Rum", "amount":0.05});
Mojito.printIngredients();

That throws:

TypeError: Cannot set property 'ingredients' of undefined

If I change my code into :

this.ingredients = [];

it works but the printIngredients() method prints undefined twice. When I do:

var array = [];
array.push({"a":1, "b":2});
console.log(array[0].a, array[0].b)

everything works as I would expect it to. Can someone clarify what I'm doing wrong and where my thoughts got mixed up?

asked May 27, 2016 at 13:54
4
  • 1
    this doesn't have prototype property Commented May 27, 2016 at 13:55
  • this.prototype.ingredients = []; should be this.ingredients = [];. this refers to newly created coctail instance, that doesn't have prototype property. Commented May 27, 2016 at 13:56
  • console.log(this.ingredients[i].fluid); (notice the i). + what has been mentioned above. Commented May 27, 2016 at 13:57
  • What you're trying to do really won't involve the prototype at all. You need a list of ingredients that's distinct for each cocktail, not a list that globally records ingredients for all cocktails. Commented May 27, 2016 at 13:57

3 Answers 3

3

Change your code to

function cocktail(){
this.ingredients = []; //this doesn't have prototype property
this.printIngredients = function() {
 var i;
 for (i = 0; i<this.ingredients.length; ++i) {
 console.log(this.ingredients[i].fluid);//use the counter variable to get the fluid value at current counter value 
 console.log(this.ingredients[i].amount);//use the counter variable to get the amount value at current counter value 
 }
 }
}
var Mojito = new cocktail();
console.log(Mojito.ingredients)
Mojito.ingredients.push({"fluid":"White Rum", "amount":0.05});
Mojito.printIngredients();
answered May 27, 2016 at 13:57
Sign up to request clarification or add additional context in comments.

2 Comments

Could you add an explanation.
@putvande sure, added the same inline.
0

Alternatively, if you are familiar with class-based languages, you could use modern JavaScript to avoid some of the confusion.

class Cocktail {
 constructor() { 
 this.ingredients = [] 
 }
 printIngredients() {
 // let is like var, but scoped to blocks instead of functions
 // for...of iterates on values instead of keys/indices
 for (let ingredient of this.ingredients) {
 console.log(ingredient.fluid)
 }
 }
}

This kind of JavaScript is available from:

  • Chrome 49
  • Edge 13
  • Firefox 44
  • Node.js 6

Documentation:

answered May 27, 2016 at 14:51

Comments

0

well, first you want to remove printIngredients method out of the constructor function, it will improve performance when it comes to a larger project since you don't have to create different copies every time you instantiate the constructor function, secondly, it is a convention to capitalize the first letter of your constructor. Last but not least, use let and const as they limit the scope to block rather than var that's function scope.

function Cocktail(){
this.ingredients = []; 
}
Cocktail.prototype.printIngredients = function() {
 // for in ... iterates on keys rather than values
 for (let i in this.ingredients) {
 console.log(this.ingredients[i].fluid);//use the counter variable to get the fluid value at current counter value 
 console.log(this.ingredients[i].amount);//use the counter variable to get the amount value at current counter value 
 }
 }
const Mojito = new Cocktail();
console.log(Mojito.ingredients)
Mojito.ingredients.push({"fluid":"White Rum", "amount":0.05});
Mojito.printIngredients();
answered Mar 14, 2019 at 19:24

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.