2009-12-11 31 views
29

Tôi đang tạo trò chơi Javascript với thẻ canvas và tôi đang sử dụng vòng lặp nâng cao để cập nhật vị trí trình phát.Hành vi lạ trong Javascript được tăng cường cho ... trong vòng lặp

Tóm lại:

var actors = new Array(); 

var player = new Actor(0, 0, img); 

actors[0] = player; 

function update_positions() { 
    //position 1 
    for(var a in actors) { 
     //position2 
     a.xpos += a.xvel; 
     a.ypos += a.yvel; 
    } 
} 

Ngay bên ngoài của vòng lặp for ở vị trí 1, tôi có thể truy cập vào các giá trị chính xác của diễn viên [0] .xvel. Bên trong vòng lặp for tại vị trí 2, a.xvel không xác định. Ai đó có thể giải thích cho tôi điều gì đang xảy ra?

+1

Vui lòng xem câu hỏi này cũng http://stackoverflow.com/questions/1886179/why-does-javascript-turn-array-indexes-into-strings-when-iterating/1886259#1886259 – pramodc84

+3

[Không sử dụng cho -in-vòng cho mảng ở tất cả] (http://stackoverflow.com/q/500504/1048572) – Bergi

Trả lời

79

Tuyên bố for...in có nghĩa là để được sử dụng để lặp qua thuộc tính đối tượng, bằng cách xem mã của bạn dường như actors là một Array (bạn đang thiết lập các yếu tố ban đầu với chỉ số 0).

Tuyên bố này cũng sẽ crawl up chuỗi mẫu, nếu bạn đã mở rộng Array.prototype các thuộc tính đó sẽ được lặp lại và thứ tự lặp lại không được bảo hành.

tôi sẽ khuyên bạn nên tránh problems và lặp sử dụng một bình thường đối với vòng lặp:

for (var i = 0; i < actors.length; i++) { 
    actors[i].xpos += actor.xvel; 
    actors[i].ypos += actor.yvel; 
} 

Nếu tôi sai, và actors không phải là một mảng, tôi sẽ khuyên bạn nên sử dụng phương pháp hasOwnProperty, để đảm bảo rằng tài sản tồn tại trong đối tượng chính nó, không lên đâu đó trong chuỗi ban đầu:

for (var name in object) { 
    if (object.hasOwnProperty(name)) { 
    // 
    } 
} 
+9

+1 chỉ là những gì tôi đã gõ :-) Thực sự, thực sự ** không sử dụng ** 'cho ... in' trên mảng. – bobince

+24

gosh! tất cả công nghệ web dường như hoàn toàn phản trực giác. Cảm ơn – Maleev

2

Hãy thử sử dụng actors[a].xpos thay vì chỉ a.xpos.

Xem tại đây để biết thêm thông tin về JavaScript for-in loops.

4

có vẻ như bạn đang cố truy cập các thuộc tính đối tượng trên tên chứ không phải giá trị ở đây. chỉ mục, trong trường hợp này là '0', được gán cho 'a' trong vòng lặp for/in.

điều bạn muốn làm là truy cập giá trị của thành viên mảng, ví dụ: diễn viên [a].

thử điều này:

for(var a in actors) { // a=0 the first time around the loop, 
    actor = actors[a]; // same thing as actors[0]; 
    actor.xpos += actor.xvel; 
    actor.ypos += actor.yvel; 
} 
+0

Cảm ơn.Tôi sẽ bắt đầu gọi nó là LiveScript từ giờ trở đi để ngăn mình bối rối. – Spencer

2

Các for (x in y) lặp cấu trúc thông qua các chỉ số của một mảng, không phải thành viên của nó.

0

Một lựa chọn khác là sử dụng các thư viện underscore:

_.each(actors, function(a) { 
    a.xpos += a.xvel; 
    a.ypos += a.yvel; 
}); 

hoặc nếu bạn không muốn sử dụng dấu gạch dưới nhưng đang sử dụng JQuery dù sao, sau đó bạn có thể làm:

$.each(actors, function(i, a) { 
    a.xpos += a.xvel; 
    a.ypos += a.yvel; 
}); 

Một tính năng tốt đẹp của mô hình chức năng này lặp đi lặp lại là bạn có thể sử dụng để var khai báo các biến trong vòng lặp được đưa vào cơ thể của vòng lặp, giúp tránh bị cắn bởi các quy tắc phạm vi biến số lẻ của JavaScript.

Các vấn đề liên quan