2014-11-29 3 views
0

Я делаю игру, в которой у меня есть несколько объектов плитки, хранящихся в массиве, и я пытаюсь вызвать функцию «обновление», чтобы нарисовать плитки на экране.Как вызвать функцию для всех свойств объекта?

Мой сценарий:

var canvas = document.getElementById("game canvas"); 
canvas.width = 600; 
canvas.height = 300; 
var g = canvas.getContext("2d"); 
var grass = new Image(); 
grass.src = "grass.png"; 
setInterval(draw,1000/60); 

function tile(x,y,img) { 
    this.x = x; 
    this.y = y; 
    this.img = img; 
    this.update = function() { 
     g.drawImage(this.img,this.x,this.y); 
    } 
} 
var maps = { 
    map1:{ 
     tiles:[ 
      new tile(0,0,grass), 
      new tile(0,32,grass) 
     ], 

     update:function() { 
      for (var i in this.tiles) { 
       i.update(); 
      } 
     } 
    } 
}; 

function draw() { 
    maps.map1.update(); 
} 

Я также попытался использовать объект вместо массива для контейнера плитки, но это не сработало. Он выводит эту ошибку в консоли:

TypeError: i.update is not a function 
+0

попробовать i.apply (нуль, обновление) –

+0

Поиск «JavaScript, итерация массив» и «JavaScript, так как в». – user2864740

+0

http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript/9329476#9329476, http://stackoverflow.com/questions/500504/why-is-using-for -in-with-array-iteration-such-the-bad-idea, http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/3010848#3010848 – user2864740

ответ

1

Когда вы используете для ... в цикле, i фактически со ссылкой на имя свойства объекта. В этом случае tiles является массивом, поэтому i можно рассматривать как индекс в этом массиве (будьте осторожны, но массивы в JS являются в основном просто специальными объектами с индексами в качестве имен свойств).

ОДНАКО, как @ jfriend00 отметил в комментариях, for..in Перечислит по всем свойствам объекта и, следовательно, может получить доступ к некоторым вещам, которые не могли бы быть то, что вы ожидаете, или объекты, которые не имеют в update() позвонить ,

В то время как вы можете сделать это:

update:function() { 
    for (var i in this.tiles) { 

     // get the current tile 
     this.tiles[i].update(); 
    } 
} 

лучше использовать либо forEach цикл в массиве, или использовать стандартный for цикл:

update:function() { 

    // update each tile 
    this.tiles.forEach(function(tile) { 
     tile.update(); 
    } 
} 

или

update:function() { 

    // normal for loop for safe indexing 
    for (var i = 0; i < this.tiles.length; i++) { 
     this.tiles[i].update(); 
    } 
} 

More info в течение в

SO Answer, что говорит о всех типах методов итерации

+0

Вы никогда не должны использовать структуру ' for (var i in this.tiles) 'в массиве. Это выполняет итерацию всех перечислимых свойств массива (которые могут включать некоторые свойства объекта), а не только элементы массива. Вы можете безопасно использовать 'for (var i = 0; i jfriend00

+0

@ jfriend00 приятно знать! Я добавлю это в ответ. – theoperatore

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