ทำความรู้จัก Loop ประเภท for...in และ for...of การใช้งานและความแตกต่างใน JavaScript
· 3 min read
Table of contents
Intro
สวัสดีครับ จะว่าไป Loop iterators ของภาษา JavaScript ก็มีเยอะมากนะครับ ผมเคยเขียนอธิบายไว้ที่นี่ ความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript
แต่บทความนี้จะพูดถึงการดำเนิน Loop 2 ชนิด (อาจจะไม่คุ้น) ที่เป็นคุณสมบัติใหม่ตั้งแต่ JS ES5/ES6 คือ
ที่จริงทั้ง 2 คือ Loop แต่ก็มีความแตกต่างกันพอสมควร ดังนั้นต้องทำความใจดี ๆ เพราะอาจจะทำให้สับสนสำหรับการใช้งานพอสมควร
TL; DR;
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...
สรุป
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"]