2010-05-29 12 views
5

Tôi đang sử dụng Google Chrome cho thử nghiệm này: Trái với trực giác, vòng lặp đầu tiên cảnh báo "chuỗi" 3 lần, trong khi vòng lặp thứ hai cảnh báo "số" 3 lần.Khi lặp lại các giá trị, tại sao typeof (giá trị) trả về "chuỗi" khi giá trị là một số? Javascript

numarray = [1, 2, 3]; 

//for-each loop 
for(num in numarray) 
    alert(typeof(num)); 

//standard loop 
for(i=0; i<numarray.length; i++) 
    alert(typeof(numarray[i])); 

Tôi đã mong cả hai vòng lặp cảnh báo "số" 3 lần. Vòng lặp đầu tiên được thực hiện như thế nào trong Javascript? Nói cách khác, nếu for-each là cú pháp đường, tương đương với nó bằng cách sử dụng một vòng lặp tiêu chuẩn là gì?

Ngoài ra, có cách nào để lặp qua không gian tên của đối tượng bằng cách sử dụng vòng lặp chuẩn không? Tôi đang tìm cách chạm vào từng phương pháp và thuộc tính của một số đối tượng bằng cách sử dụng vòng lặp của loại thứ hai. Tôi mới sử dụng Javascript và mọi trợ giúp đều được đánh giá cao, cảm ơn.

+0

Nó cũng cảnh báo 'chuỗi' trong IE. – Senthil

+0

có thể trùng lặp của [Chỉ mục mảng JavaScript một chuỗi hoặc một số nguyên?] (Http://stackoverflow.com/q/27537677/1048572) – Bergi

Trả lời

6

Lý do bạn thấy "chuỗi" được trả về trong vòng lặp đầu tiên là num là chỉ số mảng , không phải là giá trị numarray tại chỉ mục đó. Hãy thử thay đổi vòng lặp đầu tiên của bạn để cảnh báo num thay vì typeof num và bạn sẽ thấy rằng nó nhô ra 0, 1 và 2, đó là các chỉ báo chứ không phải giá trị của mảng của bạn.

Khi bạn sử dụng vòng lặp for in, bạn đang lặp qua các thuộc tính của đối tượng, không chính xác tương đương với vòng for trong ví dụ thứ hai của bạn. Mảng trong JavaScript thực sự chỉ là các đối tượng có số thứ tự như tên thuộc tính. Chúng được coi là chuỗi như xa như typeof là có liên quan.

Edit:

Như Matthew chỉ ra, bạn đang không được bảo đảm để có được các mục trong mảng trong bất kỳ thứ tự cụ thể khi sử dụng một vòng lặp for in, và một phần vì lý do đó, nó không được khuyến khích để lặp thông qua mảng như vậy.

filip-fku hỏi khi nào sẽ hữu ích khi sử dụng for in, với hành vi này. Một ví dụ là khi tên thuộc tính tự có ý nghĩa, điều đó không thực sự đúng với các chỉ báo mảng. Ví dụ:

var myName = { 
    first: 'Jimmy', 
    last: 'Cuadra' 
}; 

for (var prop in myName) { 
    console.log(prop + ': ' + myName[prop]); 
} 

// prints: 
// first: Jimmy 
// last: Cuadra 

Cũng cần lưu ý rằng các vòng lặp for in cũng sẽ lặp qua các thuộc tính của chuỗi nguyên mẫu của đối tượng. Vì lý do đó, điều này thường là cách bạn muốn xây dựng một vòng lặp for in:

for (var prop in obj) { 
    if (obj.hasOwnProperty(prop)) { 
    // do something 
    } 
} 

này một tấm séc để xem nếu tài sản được xác định bởi các đối tượng chính nó và không phải là một đối tượng nó kế thừa từ thông qua nguyên mẫu chuỗi.

+2

Không có gì đảm bảo rằng các phần tử mảng sẽ được truy cập theo thứ tự. Xem [for ... in] (https://developer.mozilla.org/en/core_javascript_1.5_reference/Statements/for...in) tại MDC: "lặp qua một mảng có thể không truy cập các phần tử theo thứ tự số". Đây là lý do chính cho..in thường không được đề xuất cho mảng. –

+0

+1 @Jimmy: Cảm ơn lời giải thích. – Senthil

+0

Thú vị! Khác với những gì người ta mong đợi từ C#/Java .. Nhưng làm thế nào điều này tốt hơn viết một cách rõ ràng tiêu chuẩn cho vòng lặp, khi tất cả các bạn nhận được là các chỉ số thay vì các giá trị mảng tự? I E. tại sao bạn sẽ sử dụng điều này khi tất cả các bạn đang nhận được chỉ số nào? (Tôi đoán tôi có thể thấy một sử dụng cho mảng kết hợp). –