2013-10-10 35 views
4

我努力学习面向对象的JavaScript跑进以下问题:修改全局变量基于对象属性

我有一个对象的构造函数(是正确的术语?)这样的:

function itemCreator(itemName, itemType, itemPositionX, itemPositionY) { 
      this.itemName = itemName; 
      this.itemType = itemType; 
      this.itemPositionX = itemPositionX; 
      this.itemPositionY = itemPositionY; 
      allItems.push(this); //store all items in a global variable 
      }//end itemCreator; 


//then I use it to create an object 

megaRocket = new itemCreator (
      'megarocket', 
      'item_megarocket', 
      108, 
      475 
      ) 

现在我意识到我也需要映射这些对象来根据对象所具有的“itemType”来修改不同的全局变量。这是我卡住的地方。我怎样才能使一个全局变量,只有具有特定itemType属性的对象可以修改?

例如,我想创建一个对象,该对象增加一个名为amountOfMegarockets的变量,但前提是该对象的itemType是“item_megarocket”。

我后来循环这些项目的数组,看看玩家物体接触他们计划(收集项):

function checkForItems(){ 
       var itemLen =allItems.length; 
       for (i=0; i < itemLen; i++){ 
       var itemObject = allItems[i]; 

       if (//checking for "collisions" here 
       (ship.x < (itemObject.itemBitmap.x + itemObject.size) && (ship.x + shipWidth) > itemObject.itemBitmap.x) && 
       (ship.y < (itemObject.itemBitmap.y + itemObject.size) && (ship.y + shipWidth) > itemObject.itemBitmap.y) 
       ){ 
       itemObject.actor.y = -500; //just removing the item from canvas here (temporary solution) 
       // Here comes pseudo code for the part that I'm stuck with 
       variableBasedOnItemObject.itemType++; 

       } 

我希望我的解释是有道理的人!

编辑:

BERGI的回答最有意义给我,但我不能让语法正确。以下是我想要使用BERGI代码:

var amounts = {}, 
allItems = []; 
function itemCreator(itemName, itemType, itemPositionX, itemPositionY) { 
this.itemName = itemName; 
this.itemType = itemType; 
this.itemPositionX = itemPositionX; 
this.itemPositionY = itemPositionY; 

(amounts[itemType]=2); // this is different from bergi's example because I need to set the initial value of the item to two 
//I also shouldn't increase the item amount on creation of the item, but only when it's specifically called from another function 
this.increaseCount = amounts[itemType]++; //this should IMO increase the itemType amount inside the amounts object when called, but it doesn't seem to work 
} 

//creating the object the way bergi suggested: 
allItems.push(new itemCreator('shootUp001', 'item_up', 108, 475)); 

现在,这里的问题的一部分:

function checkForItems(){ 
       var itemLen =allItems.length; 
       for (i=0; i < itemLen; i++){ 
       var itemObject = allItems[i]; 

       if (my condition here) 
       ){ 

//code below is not increasing the value for the current itemType in the amounts object. 
//Probably a simple syntax mistake? 
       itemObject.itemType.increaseCount; 

       } 

      } 

      } 

为什么我itemObject.itemType.increaseCount的呼叫;不增加amount.itemType的值?

+1

IMO,这是不正确的方法所有。你应该把你的逻辑分成不同的类,而不是单一的类。 – 2013-10-10 07:58:47

+0

这不是一个庞然大物类IMO,因为所有的“项目”都非常相似,并且共享相同的属性。不同项目之间唯一的主要区别应该是它们影响的计数器变量。 –

+2

任何以“修改全局变量”开头的问题都已经提出了错误的问题。 –

回答

1

递增一个名为amountOfMegarockets全局变量,但前提是ITEMTYPE为该对象是“item_megarocket”。

不要为每个项目类型使用全局变量。请使用一个对象(在全局或本地作用域中)来计算其属性上每种类型的数量。

var amounts = {}, 
    allItems = []; 
function Item(itemName, itemType, itemPositionX, itemPositionY) { 
    this.itemName = itemName; 
    this.itemType = itemType; 
    this.itemPositionX = itemPositionX; 
    this.itemPositionY = itemPositionY; 

    amounts[itemType]++ || (amounts[itemType]=1); // count by type 
    allItems.push(this); // store all items 
} 

请注意,我不会把所有Item情况下,在默认情况下的阵列,更好地省略线,让它做来电:

allItems.push(new Item('megarocket', 'item_megarocket', 108, 475)); 
+0

嗨!这看起来很有希望,我现在就开始测试它,如果你有时间的话,可以用 这个数字来解释数量[itemType] ++ | |(金额[itemType] = 1); 在我看来,你每次使用这个函数都会增加变量吗?此外,“or”语句(该行的右侧部分)只是另一个选项,或者它是否也用于练习? –

+0

我觉得我几乎在那里,但我似乎无法找到修改“数量”对象的正确语法。我将编辑我的问题以更好地展示我如何尝试使用你的解决方案(没有运气)! –

+0

在你的代码中,'.itemType'是一个常量ty的文字名称为“itemType”。在我的代码中,我使用[括号表示法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Member_Operators)从'itemType'中获取动态属性名称值。是的,每次构造函数运行时,我都会增加该属性。 OR部分在左边部分计算为'NaN'时执行,因为该属性之前未定义。更明确的说法是:if(itemType in amount)amouts [itemType] ++; else amount [itemType] = 1;' – Bergi

0

你可以做一些事情像

(function (global) { 
    // create a scope 
    var allItems = []; 
    global.itemCreator = function(itemName, itemType, itemPositionX, itemPositionY) { 
     this.itemName = itemName; 
     this.itemType = itemType; 
     this.itemPositionX = itemPositionX; 
     this.itemPositionY = itemPositionY; 
     allItems.push(this); //store all items in a global variable 
     }//end itemCreator; 
})(this); 

这会工作。但严重不要让你的代码变得太复杂,使私有变种。如果有人想用调试器作弊,他总会找到一种方法来做到这一点。

----编辑 如果您想探微访问全局变量的基础上ITEMTYPE你可以做一些喜欢的事情:

function checkForItems(){ 
    var itemLen =allItems.length; 
    for (i=0; i < itemLen; i++){ 
     var itemObject = allItems[i]; 

     if (//checking for "collisions" here 
      (ship.x < (itemObject.itemBitmap.x + itemObject.size) && (ship.x + shipWidth) > itemObject.itemBitmap.x) && 
      (ship.y < (itemObject.itemBitmap.y + itemObject.size) && (ship.y + shipWidth) > itemObject.itemBitmap.y) 
     ){ 
      itemObject.actor.y = -500; //just removing the item from canvas here (temporary solution) 
      // Here comes pseudo code for the part that I'm stuck with 
      if (window[itemObject.itemType + "Data"])) { 
       variableBasedOnItemObject.itemType++; 
      } else { 
       window[itemObject.itemType + "Data"] = { 
        itemType: 1 
       } 
      } 
     } 
    } 
} 
+0

我不确定我是否理解这个答案。假设有一个名为“amountOfMegarockets”的全局变量。只有当“this”具有megaRocket的itemType时,我将如何编写一个修改该变量的函数? –

+0

好的。忘记我的答案。我不明白你的问题对不起。你可以使用字符串来访问你的var,这样你就可以像索引一样:window [“amountOf”+ this.itemType +“s”]。push(this)例如但是照顾复数并且对象存在(例如: window.hasOwnProperty(“amountOf”+ this.itemType +“s”) – peernohell