2013-10-10 36 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