Coming from a low level C background, I'm having difficulty understanding this prototype, function constructor, and "classical classing" constructs.
For the purpose of learning, I've tried to design a menu system.
The result should be usable like so:
var testmenu = new menu();
testmenu.addfood("burger");
testmenu.addfood("chips");
testmenu.adddrink("fanta");
testmenu.adddrink("coke");
alert(JSON.stringify(testmenu));
testmenu.foods[0].remove();
alert(JSON.stringify(testmenu));
This is what I came up with:
function menu() {
var that = this;
this.foods = new Array();
this.drinks = new Array();
this.addfood = function(name) {
that.foods[that.foods.length] = new food(name);
// this seems silly, is there a way of getting the index in the array without giving it an index property?
that.foods[that.foods.length - 1].index = that.foods.length - 1;
// can't store the menu
//that.foods[that.foods.length - 1].menu = that;
return that.foods.length - 1;
}
this.adddrink = function(name) {
that.drinks[that.drinks.length] = new drink(name);
// same problem as with food
that.drinks[that.drinks.length - 1].index = that.drinks.length - 1;
//that.drinks[that.drinks.length - 1].menu = that;
return that.drinks.length - 1;
}
}
var menuItem = {
name: "New menuItem",
remove: function() {
alert("Remove: " + this.name + " at index " + this.index);
// No way of telling what menu the menuItem is in, I have to assume testmenu
testmenu[this.menuItemType].splice(this.index, 1);
//this.menu[this.menuItemType].splice(this.index, 1);
}
};
function food(name) {
if(name) this.name = name;
this.menuItemType = "foods";
}
food.prototype = menuItem;
function drink(name) {
if(name) this.name = name;
this.menuItemType = "drinks";
}
drink.prototype = menuItem;
var testmenu = new menu();
testmenu.addfood("burger");
testmenu.addfood("chips");
testmenu.adddrink("fanta");
testmenu.adddrink("coke");
alert(JSON.stringify(testmenu));
testmenu.foods[0].remove();
alert(JSON.stringify(testmenu));
There are two problems I am having:
Your prototypes and "classes" look quite fine.
there is no way for the remove function to know which menu to remove the menuItem from.
Sure, how would you know? You might want to pass it as a parameter. However, the more OOP way would be to put the remove
method on the menu
class (the collection, on which also the add
methods are defined) and to pass the item as an argument, instead of having it on the menuitem
.
// can't store the menu //that.foods[that.foods.length - 1].menu = that;
What stops you? Sure, JSON.stringify
throws an error if you pass in an object with cyclic references. You might want to use a debugger, or at least check the error console. Or try to do console.log(testmenu)
instead of the alert
, so that you don't need to serialize it but can dynamically inspect it.
there is no way to get the index of an array item, you have to store it as a property.
Well, you could search for it using the indexOf
array method if you don't want to store the index. It would become inaccurate anyway as soon as you remove other items.