Skip to main content

ทำความรู้จัก Loop ประเภท for...in และ for...of การใช้งานและความแตกต่างใน JavaScript

· 3 min read

Intro

สวัสดีครับ จะว่าไป Loop iterators ของภาษา JavaScript ก็มีเยอะมากนะครับ ผมเคยเขียนอธิบายไว้ที่นี่ ความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript

แต่บทความนี้จะพูดถึงการดำเนิน Loop 2 ชนิด (อาจจะไม่คุ้น) ที่เป็นคุณสมบัติใหม่ตั้งแต่ JS ES5/ES6 คือ

ที่จริงทั้ง 2 คือ Loop แต่ก็มีความแตกต่างกันพอสมควร ดังนั้นต้องทำความใจดี ๆ เพราะอาจจะทำให้สับสนสำหรับการใช้งานพอสมควร

TL; DR;

  • For-of คือ Loop เพื่อหา Values ทีละตัว
  • For-in คือ Loop เพื่อหา Keys ทีละตัว

for...of

หา Values ทีละตัว

Syntax
for (variable of iterable) {
//statement
}
Live Editor
() => {
  
  const data = [1, true, false, "Hello"] // ใช้กับข้อมูลชนิด Array ได้
  
  // const data = {a: 1, b: 2, c: 3, d: 4} // ใช้กับข้อมูลชนิด Object ไม่ได้
  
  // const data = "hello world!" // ใช้กับข้อมูลชนิด String ได้
  
  const newArray = []
  
  for (const a of data) {
    newArray.push(a)
  }
  
  return newArray.toString()
}
Result
Loading...

for...in

หา Keys ทีละตัว

Syntax
for (variable in object) {
//statement
}
Live Editor
() => {

  // const data = [1, true, false, "Hello"] // ใช้กับข้อมูลชนิด Array ได้
  
  const data = {a: 1, b: 2, c: 3, d: 4} // ใช้กับข้อมูลชนิด Object ได้
  
  // const data = "hello world!" // ใช้กับข้อมูลชนิด String ได้
  
  const newArray = []
  
  for (const a in data) {
    newArray.push(a)
    // newArray.push(data[a]) // ลองรันบรรทัดนี้ หากต้องการใช้ key เข้าถึง value
  }

  return newArray.toString()
}
Result
Loading...

สรุป

  • For-of คือ Loop เพื่อหา Values ทีละตัว
  • For-in คือ Loop เพื่อหา Keys ทีละตัว
Methodใช้กับ Arrayใช้กับ Objectใช้กับ String
For in
For of

แถม 1

ที่จริง for...of สามารถเข้าถึงทั้ง Value และ Key ได้เช่นกัน ดังนี้

Live Editor
() => {

  const data = {a: 1, b: 2, c: 3, d: 4}

  const newArray = []

  for (const [key, value] of Object.entries(data)) {
    newArray.push({ [key]: value })
  }

  return JSON.stringify(newArray)
}
Result
Loading...

แถม 2

ที่จริงมี For await of ... ด้วยนะครับ โดยใช้กับ Loop บางกรณีที่เป็นแบบ Asynchronous iterators โดยหลักการคือการ Loop Promises Array (ที่ต้องรอผลลัพธ์)

Syntax
for await (variable of iterable) {
//statement
}
การทำซ้ำบน Promises Array
async function main() {

const fetchData = async () => {
const response = await fetch('https://api.github.com/repos/kongvut/laravel-best-practices/commits');
const commits = await response.json();
return commits[0].author.login;
}

const fetchData2 = () => {
return fetch('https://api.github.com/repos/microsoft/vscode')
.then(response => response.json())
.then(data => data.owner.login);
}

// Array of Promises
const somethingAsync = [
fetchData(),
Promise.resolve('b'),
Promise.resolve('c'),
fetchData2()
];

// Loop for await ... of
for await (const x of somethingAsync) {
console.log(x);
}
}

main();

// Output:
// kongvut
// b
// c
// microsoft

แถมอีกหน่อยจากโค้ดด้านบนถ้าเราใช้ Promise all แทน for await ก็จะได้ประมาณนี้ 👍

// Array of Promises
const somethingAsync = [
fetchData(),
Promise.resolve('b'),
Promise.resolve('c'),
fetchData2()
];
const [...x] = await Promise.all(somethingAsync);
console.log(x); // ["kongvut", "b", "c", "microsoft"]

References

Loading...