2013-10-10 8 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++; 

       } 

Я надеюсь, что мое объяснение имеет смысл кому-то!

EDIT:

ответ BERĢI делает больше смысла для меня, но я не могу получить правильный синтаксис. Вот как я пытаюсь использовать код Берги в:

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; не увеличивая значение amounts.itemType?

+1

ИМ, это не правильный подход в все. Вы должны разделить свою логику на разные классы, а не на один монолитный класс. –

+0

Это не монолитный класс IMO, потому что все «элементы» очень похожи и имеют одни и те же свойства. Единственное основное различие между различными элементами - это переменная счетчика, на которую они влияют. –

+2

Любой вопрос, начинающийся с «изменить глобальную переменную», уже задает неправильный вопрос. –

ответ

1

Increment глобального переменным называется 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); Это похоже на то, что вы увеличиваете переменную каждый раз, когда эта функция используется? Также является оператором «или» (правая часть этой строки) просто другим вариантом или это также используется на практике? –

+0

Я чувствую, что я почти там, но я не могу найти правильный синтаксис для модификации объекта «количество». Я отредактирую свой вопрос, чтобы лучше показать, как я пытаюсь использовать ваше решение (без везения)! –

+0

В вашем коде '.itemType' является константой с буквальным именем «itemType». В моем коде я использую [примечание в виде скобок] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Member_Operators), чтобы получить динамическое имя свойства из 'itemType' стоимость. Да, я увеличиваю это свойство каждый раз, когда выполняется конструктор. OR-часть выполняется, когда левая часть вычисляет значение «NaN», потому что свойство ранее не было определено. Более явный: 'if (itemType в количествах) 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); 

это будет работать. но серьезно не усложняйте слишком заманить свой код juste, чтобы сделать private var. если кто-то хочет обмануть использование отладчика, он всегда найдет способ сделать это.

---- редактировать Если вы Juste хотите получить доступ к глобальным переменным базам на 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» имеет itemType megaRocket? –

+0

ОК. забыть мой ответ. Я не понимаю ваш вопрос, извините. вы можете использовать строку для доступа к вашему var, чтобы вы могли делать такие вещи, как: window ["amountOf" + this.itemType + "s"]. Например, нажмите (это), но позаботьтесь о множественном числе и о том, что объект существует (например: window.hasOwnProperty ("amountOf" + this.itemType + "s") – peernohell

Смежные вопросы