Hi 🤓 Cảm ơn bạn đã ghé thăm blog này, nếu những bài viết trên blog giúp ích cho bạn. Bạn có thể giúp blog hiển thị quảng cáo bằng cách tạm ngừng ad blocker 😫 và để giúp blog duy trì hoạt động nếu bạn muốn.
Cảm ơn bạn!

Chào các bạn, để tiếp tục nội dung chủ đề học JavaScript cơ bản, hôm nay chúng ta cùng tìm hiểu về vòng lặp for...in trong JavaScript nhé 😁.

JavaScript for...in loop

Vòng lặp for...in lặp qua enumerable properties. Một thuộc tính là enumerable khi giá trị enumerable của thuộc tính đó là true.

Giá trị enumerable sẽ mặc định là true khi chúng ta tạo thuộc tính thông qua phép gán như bên dưới:

object.propertyName = value;

hoặc là:

let obj = {
    propertyName: value,
};

Sau đây chúng ta cùng xem qua cú pháp của for...in:

for(const propertyName in object) {
    // ...
}

Ví dụ:

const obj = {
  blog: "homiedev.com",
  categories: ["ReactJS", "JavaScript", "TypeScript"],
  isFrontEndBlog: true,
};

for(const prop in obj) {
    console.log(prop + ' 👉 ' + obj[prop]);
}

Kết quả chúng ta được:

blog 👉 homiedev.com
categories 👉 ReactJS,JavaScript,TypeScript
isFrontEndBlog 👉 true

Trong ví dụ trên, chúng ta đã sử dụng vòng lặp for...in để lặp qua các thuộc tính của object obj. Đẻ lấy giá trị của từng thuộc tính, chúng ta sử dụng obj[prop].

Lưu ý khi sử dụng for...in

Khi lặp qua thuộc tính của một object (object này kế thừa từ một object khác) sử dụng for...in, nó sẽ lặp qua các thuộc tính được kế thừa nếu thuộc tính là enumerable. Hay nói cách khác thì for...in sẽ kiểm tra prototype chain và lặp qua các thuộc tính có enumerabletrue. Để hiểu rõ hơn thì các bạn xem ví dụ sau:

const user = {
  fullName: 'Nguyen Anh Vu',
  age: 22
}

Object.defineProperty(user, 'address', {
    value: 'Ho Chi Minh City',
    // mặc định enumerable: false
});

const author = Object.create(user);
author.blog = 'homiedev.com';

for(const prop in author) {
    console.log(prop);
}

Kết quả ví dụ trên:

blog
fullName
age

Ở ví dụ trên, object author có prototype của nó tham chiếu đến object user. Do đó, vòng lặp for...in sẽ kiểm tra prototype và hiển thị các thuộc tính có giá trị enumerabletrue.

Nếu chỉ muốn lấy các own property (thuộc tính của chính object đó), các bạn sử dụng method hasOwnProperty():

for(const prop in author) {
  if(author.hasOwnProperty(prop)) {
    console.log(prop);
  }
}

Kết quả:

blog

Chúng có thể sử dụng for...of kết hợp với Object.keys() cũng cho kết quả tương tự. Object.keys() sẽ trả về mảng chứa tên các thuộc tính là enumerable của chính object đó (own property):

for(const prop of Object.keys(author)) {
    console.log(prop);
}

// blog

Sử dụng for...in với mảng

Đây là một bad idea nếu chúng ta kết hợp for...in với mảng. Chúng ta cùng coi ví dụ sau, ở ví dụ này, for...in hoạt động tốt:

let total = 0;
const numbers = [5, 10, 15];

for (const index in numbers){
  total += numbers[index];
}

console.log(total); // 30

Giả sử, trong một thư viện JavaScript các bạn đang sử dụng có đặt một thuộc tính vào built-in Array như sau:

Array.prototype.defaultValue = 1;

Lúc này sẽ có vấn để khi chúng ta sử dụng for...in, cùng xem ví dụ sau:

// giả sử có giá trị này trong Array.prototype
Array.prototype.defaultValue = 1;

let total = 0;
const numbers = [5, 10, 15];

for (const index in numbers){
  console.log({ index, value: numbers[index] });

  total += numbers[index];
}

console.log(total);

Kết quả như sau:

{index: '0', value: 5}
{index: '1', value: 10}
{index: '2', value: 15}
{index: 'defaultValue', value: 1}
31

Một ví dụ khác:

const a = []; // tạo empty array
a[3] = 15;   // đặt giá trị cho phần tử thứ 4 là 15

for (var i = 0; i < a.length; i++) {
    console.log(a[i]);
}

/* 
   undefined
   undefined
   undefined
   15
*/

Tuy nhiên khi sử dụng for...in, nó sẽ bỏ qua 3 phần tử đầu tiên:

for (const key in a) {
    console.log(a[key]);
}

// 15

🎉 Như vậy là chúng ta đã tìm hiểu về for...in trong JavaScript. Hi vọng bài viết giúp ích cho các bạn. Nếu muốn tìm hiểu sự khác nhau giữa for...infor...of các bạn có thể đọc bài viết: Khác nhau giữa for...in và for...of JavaScript.

Chúc các bạn học tốt 😁.

Có thể bạn thích ⚡
homiedev
About Me

Hi, I'm @devnav. Một người thích chia sẻ kiến thức, đặc biệt là về Frontend 🚀. Trang web này được tạo ra nhằm giúp các bạn học Frontend hiệu quả hơn 🎉😄.

Chúc các bạn tìm được kiến thức hữu ích trong blog này 😁😁.