Developer javascript nên dừng lại for...in ngay bây giờ

Nội dung bài viết

Tôi đảm bảo những ai chưa đọc bài viết này or chưa đọc các bài viết như thế này thì vẫn sẽ vô tư sử dụng loop for in một cách thoải mái và tự tin. Cũng như thầm cảm ơn for in một cách thần thánh. 

JavaScript's for...in loop lặp vô số thuộc tính của một obejct hay array. Thế nhưng trong bài viết này tôi sẽ đề cập đến một loại cũng giúp chúng ta hằng ngày để giải quyết vòng lặp đó là for..in. Nhưng các bạn biết không trong quá trình làm việc mà code của tôi có vấn đề và phát hiện ra điều này không ai khác thủ phạm là for in. 

Trước đây chúng ta đã nói về những cách lặp khác nhau trên array or object. Ví dụ như for or forEach. Và tôi cũng đã viết một bài về sự khác nhau giữa for và forEach. 

Xe thêm bài viết: Trời Sinh Ra For Loop Sao Còn Sinh Array.ForEach Trong Javascript?

Tham gia cùng chúng tôi:

Facebook: Cộng đồng lập trình javascript

Facebook Cộng đồng giới thiệu bài viết, website, sản phẩm tăng traffic.

Hãy đi vào ví dụ đầu tiên để thấy for in hoạt động thế nào?

### with object
var player = {
    two: "Messi",
    one: "Ronaldo",
    zero: "AnonyStick"
};

var countdown = "";

for (var step in player) {
    countdown += player[step] + "\n";
}

console.log(countdown);
// => "Messi
//    Ronaldo
//   AnonyStick!
//    "

Tương tự đối với các mảng thì chúng ta cũng sử dụng tương tự

### with array

var player = [
    "Messi",
    "Ronaldo",
     "AnonyStick"
]

var countdown = "";

for (var step in player) {
    countdown += player[step] + "\n";
}

console.log(countdown);
// => "Messi
//    Ronaldo
//   AnonyStick!
//    "

Tuy nhiên, có ba vấn đề xảy ra với việc sử dụng phương pháp này trên array. 

Đầu tiên, for ... in cũng lặp lại các prototype properties của một đối tượng nếu các thuộc tính đó là enumerable. 

enumerable là Chỉ định xem thuộc tính có thể được trả về trong vòng lặp for / in hay không. 

Nếu chưa biết về enumerable thì các bạn nên xem qua câu hỏi ở stackoverflow: https://stackoverflow.com/questions/17893718/what-does-enumerable-mean 

### Vấn đề 1 của for..in

Array.prototype.voice = "Rooney"; //enumerable properties

var player = [
    "Messi",
    "Ronaldo",
     "AnonyStick"
] // ở đây có 3 item

var countdown = "";

for (var step in player) {
    countdown += player[step] + "\n";
}

console.log(countdown);
// xuât hiện 4 item.
//Messi
//Ronaldo
//AnonyStick
//Rooney


Nhiều bạn vẫn tinh ý và biết rằng có thể giải quyết được chuyện này đơn giản tại sao lại la hét lên đến vậy, đó là sử dụng hasOwnProperty.

Array.prototype.voice = "Rooney"; //enumerable properties

var player = [
"Messi",
"Ronaldo",
"AnonyStick"
] // ở đây có 3 item

var countdown = "";

for (var step in player) {
if (player.hasOwnProperty(step)) {
countdown += player[step] + "\n";
}
}

console.log(countdown);
//xuât hiện 3 item.
//Messi
//Ronaldo
//AnonyStick

Nhưng bạn giải quyết xong bạn có thể trơn tru mà mượt mà hơn không? Câu hỏi này để lại cho các bạn? 

### Vấn đề thứ 2 -> Sắp xếp không đúng khi sủe dụng for... in so với array ban đầu

Nếu bạn có thời gian để xem qua http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4 tôi nghĩ bạn sẽ hiểu sâu hơn. Đó thực sự không phải là vấn đề đối với một đối tượng bình thường có giá trị vốn dĩ không có thứ tự. 

Nhưng có lẽ bạn không muốn công cụ JavaScript của mình trả lại các item của mẳng theo thứ tự ngẫu nhiên, bởi vì bạn có thể nhận được kết quả bất ngờ như thế này:

console.log(countdown);
// => "AnonyStick
//    Ronaldo
//    Messi
//    "

### Vấn đề thứ 3 với lặp enumerable properties. 

Như chúng ta đã thảo luận trước đây, có thể lưu trữ các thuộc tính bổ sung trên một mảng. Điều này cũng có thể dẫn đến kết quả bất ngờ.

ví dụ:

var player = [
"Messi",
"Ronaldo",
"AnonyStick"
];

player.announcer = "Rooney";

var countdown = "";

for (var step in player) {
if (player.hasOwnProperty(step)) {
countdown += player[step] + "\n";
}
}

console.log(countdown);
// => "Messi
//Ronaldo
//AnonyStick
//Rooney

### Cuối cùng

Tham gia cùng chúng tôi:

Facebook: Cộng đồng lập trình javascript

Facebook Cộng đồng giới thiệu bài viết, website, sản phẩm tăng traffic.

Qua những ví dụ trên và vì những vấn đề này, bạn gần như sẽ không bao giờ muốn lặp lại các mảng với for...in loops. 

Thay vào đó, hãy sử dụng một vòng lặp for thông thường hoặc một trong các phương thức lặp mảng tích hợp sẵn như forEach hoặc map. 

Bây giờ bạn biết thêm một điều cần tránh khi bạn viết JavaScript an toàn và sạch sẽ trong code của bạn. 

Thanks for reading!

Bài viết có tham khảo ở nhiều nguồn:
http://adripofjavascript.com/blog/drips/the-problem-with-for-in-and-javascript-arrays.html

https://stackoverflow.com/questions/17893718/what-does-enumerable-mean