也许我(第一次使用Javascript)构造了错误的代码,但我想接受用户输入并搜索数组数组,以检查是否存在具有该名称的数组。
我第一次尝试使用eval()函数,有人告诉我这个函数不好,但当有匹配时它会起作用,但当不存在匹配时它就会失败。
该程序的基本前提是有一个包含位置的数组,这些位置随后是包含食物项目的数组。用户输入食物的名称和他们想放在哪里,它将创建一个食物对象,将该对象插入数组中的正确位置,并将该项目输入到以html显示的列表中。
以下是迄今为止的所有代码:
var fridge = [];
var freezer = [];
var pantry = [];
var locations = [fridge, freezer, pantry];
function Food(name, location, locationName){
this.name = name;
this.location = location;
this.locationName = locationName;
this.displayName = function(){
alert(this.name);
};
};
function createFood(){
var name = prompt("Enter the items name:");
var locationName = prompt("Enter a location to store it:")
var location = eval(locationName);
while(locations.indexOf(location) == -1){
alert("This is not an actual location.");
locationName = prompt("Please enter another location:");
location = eval(locationName);
};
var x = new Food(name, location, locationName)
function insertFood(Food){
var a = locations.indexOf(Food.location);
locations[a].push(Food);
var list = document.getElementById(Food.locationName + "_items");
var li = document.createElement("li");
li.innerHTML = Food.name;
list.insertBefore(li, list.lastChild);
};
insertFood(x);
};
请让我知道这是不是结构错误,因为这是我的第一眼结构的想法。
谢谢!
如上所述,最好将locations
设为对象,这样就可以有一个指向同名数组的键(字符串)。
var fridge = [];
var freezer = [];
var pantry = [];
var locations = {
"fridge":fridge,
"freezer":freezer,
"pantry":pantry
};
这样做的好处是,你不需要有locationName,因为它从来没有真正发挥作用。您只需要使用本机hasOwnProperty
函数检查locations
对象是否具有与用户输入同名的属性。类似于:
if(!locations.hasOwnProperty(userInputLocation))
alert("That is not a designated location");
然后你的Food构造函数也变得更简单,只需要名称和位置属性:
function Food(name, location){
this.name = name;
this.location = location;
}
然后,您也可以直接通过名称调用任何特定位置(如果您要像在代码中那样全局声明它),或者更恰当地(如果您像在SGD的代码中那样声明对象内部的数组)通过locations[location]
调用,其中location
只是一个包含"冷冻室"、"餐具室"或"冰箱"的字符串。您也可以通过locations[someFood.location]
调用数组。
无论如何,我不太喜欢提示和警报(更不用说eval了),所以我使用输入字段创建了一个jsBin,你可以在这里查看:http://jsbin.com/pamoquwuhu/1/edit
编辑后添加:如果目标是以后要在保存食物的所有位置按食物的名称查找食物,最好在locations[location]
中添加/推送foodObj.name
,而不是整个foodObj
。然后,您可以在locations对象上使用本地for(property in object)
循环来查看所有给定食物可能存储在哪里,并将其推送到results
数组中。因此,您的findFood
函数可能包含以下内容(假设food
是要搜索的食物名称的用户输入字符串:
var results = [];
for(var loc in locations){ // loops through the property names in `locations`
if(locations[loc].indexOf(food)>=0)
results.push(loc);
}
if(!results.length){
alert(food+' was not found');
else
alert(food+' was found in '+results.toString());
假设相同的食物可以存储在多个位置,并且你想通过食物的名称找到给定的食物,那么你的食物对象的location
属性就会变得不那么重要(或者可能毫无用处)。
您使用Food作为函数/构造函数和参数名称(但这不应该是问题,但以后可能会引起麻烦),并且您从未调用insertFood
。此外,位置应该是对象而不是数组,这样您就可以像在代码中那样访问子数组。
var locations = {fridge : [], freezer:[], pantry:[]];
function Food(name, locationName){
this.name = name;
this.locationName = locationName;
this.displayName = function(){
alert(this.name);
};
};
function createFood(){
var name = prompt("Enter the items name:");
var locationName = prompt("Enter a location to store it:")
while(locationName in locations){
alert("This is not an actual location.");
locationName = prompt("Please enter another location:");
};
var x = new Food(name, locationName)
function insertFood(food){
locations[food.locationName].push(food);
var list = document.getElementById(food.locationName + "_items");
var li = document.createElement("li");
li.innerHTML = food.name;
list.insertBefore(li, list.lastChild);
};
// call the method now?
insertFood(x);
};
createFood();