了解原型和"类"

时间:2014-07-12 19:42:53

标签: javascript arrays class prototyping

来自低级别的C背景,我很难理解这个原型,函数构造函数和“经典分类”结构。

为了学习,我试图设计一个菜单系统。

  • 'menuItem'应该有'name'属性和'remove'函数。
  • 'food'应该基于menuItem,并且为了简单起见,它应该没有自定义属性或函数。
  • 'drink'应该基于menuItem,并且为了简单起见,它应该没有自定义属性或函数。
  • 'menu'应包含一系列'food','drink'和相应的功能,以添加新的'food'和'drink'。

结果应该可以这样使用:

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));

这就是我提出的:

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));

我遇到两个问题:

  • 删除功能无法知道从哪个菜单中删除menuItem。
  • 无法获取数组项的索引,您必须将其存储为属性。

1 个答案:

答案 0 :(得分:0)

您的prototypes"classes"看起来很不错。

  

remove函数无法知道从哪个菜单中删除menuItem。

当然,你怎么知道的?您可能希望将其作为参数传递。但是,将remove方法放在menu类(集合上,也定义了add方法)上的OOP方法越多,并将该项作为参数传递而不是menuitem

 // can't store the menu
 //that.foods[that.foods.length - 1].menu = that;

什么阻止了你?当然,如果传入带有循环引用的对象,JSON.stringify会抛出错误。您可能希望使用调试器,或者至少检查错误控制台。或者尝试console.log(testmenu)而不是alert,这样您就不需要序列化它,但可以动态检查它。

  

无法获取数组项的索引,您必须将其存储为属性。

如果您不想存储索引,可以使用indexOf array method搜索它。一旦你删除其他项目,它就会变得不准确。