将对象插入全局数组?

时间:2016-04-22 02:24:00

标签: javascript html5

我有一个html文件,其中包含一个表格供个人填写以接受订单。

我有一个存储对象的全局数组。对象包含添加到订单中的商品的名称,价格和数量。

<button type="button" onclick="addToOrder('app2-amount', 'House Salad', '6')">+</button> 

这是调用addToOrder()的地方。

功能:

var orderArray = [];

function addToOrder(id, nameIn, priceIn){
if (loggedIn == true){
  var quantityIn = document.getElementById(id).value;
  var totalForThisItem = priceIn*quantityIn;

  var menuObject = {
     name: nameIn,
     price: totalForThisItem,
     quantity: quantityIn
   };

   // Next we must perform a check to see if an object with the same name already exists in the order
   // If it does exist, replace it with this new object.
   if (orderArray.length == 0){
     orderArray.push(menuObject);
   }
   else{
     orderArray.forEach( function (item) {
       if (item.name == menuObject.name){
         item = menuObject;
       }
       else{
         orderArray.push(menuObject);
       }
     });
   }
   console.log("dabs " + orderArray.toString());
   }
    // If user is not logged in:
   else{
   console.log("You are not logged in. Please log in to use this feature.");
    }
 console.log(menuObject);
}

当我打印menuObject时,我认为它会超出范围,删除。我将它插入到一个全局变量中,我认为这让我感到困惑。

当我开始将不同的菜单项放入数组时,会发生一些奇怪的事情。在一种情况下,每次按下它会增加3,6,12,24等。有点好笑,但我很沮丧。

这里发生了什么?

1 个答案:

答案 0 :(得分:3)

我认为你在Javascript中略微误解了词法作用域。

var声明的作用域是功能块级别。这意味着即使您的var语句位于if块内,它也具有整个函数的作用域,并且在函数退出之前一直保持定义。由于hoisting,它们在函数的任何地方(甚至在声明之前)都是有效的。

如果你在ES6中写作,你也可以使用let declarations,其范围限定在最近的封闭块...在你的情况下,if块。这就是我认为你在这里期待的行为。

你的另一个问题是合乎逻辑的。每次通过函数时,您都使用forEach遍历数组,然后可能会为数组中的每个现有对象推送一次新对象。这就是为什么你的阵列长度有几何级数的原因。

如果您的意图是'替换数组中的匹配项(如果它已经存在),否则将其添加到结尾'然后有几种方法可以做到这一点。 Array.find是一种选择,但有几种方法可行。