Reputation: 325
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?
Upvotes: 2
Views: 9137
Reputation: 178
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();
Upvotes: 0
Reputation: 2260
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:
Documentation:
Upvotes: 0
Reputation: 68393
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();
Upvotes: 3