JavaScript
Loop Arrays & Objects
for...in กับ object
เรียนรู้ว่า `for...in` เหมาะกับ object เพราะวน property key ได้โดยตรง แล้วใช้ `obj[key]` ดึงค่าไปทำงานต่อได้
for...in กับ object — วน property key ทีละตัว
`for...in` เหมาะกับ object เพราะแต่ละรอบจะได้ **ชื่อ property key** ออกมาก่อน แล้วค่อยใช้ key นั้นไปดึงค่าด้วย `obj[key]` ให้จำภาพง่าย ๆ ว่า `for...in` เดินดู “ชื่อช่อง” ของ object ทีละช่อง
แต่ละรอบ `key` คือชื่อ property ของ object ตัวนั้น ส่วนบทนี้ให้โฟกัสที่การได้ key แล้วค่อยใช้ `obj[key]` ไปอ่านค่า
const user = { name: "Alice", age: 25, role: "admin" };
for (const key in user) {
console.log(key);
}
// "name"
// "age"
// "role"ได้ `key` เป็น string — ใช้ `obj[key]` เพื่อดูค่า
`for...in` ให้แค่ **ชื่อ key** — ถ้าต้องการค่า value ต้องใช้ **bracket notation** `obj[key]` ดึงออกมา ทำไมต้อง bracket notation: เพราะ key เป็น string ที่เปลี่ยนทุกรอบ — dot notation อย่าง `obj.key` จะหา property ที่ชื่อว่า `"key"` ตัวอักษร ไม่ใช่ค่าของตัวแปร `key`
`user[key]` ดึงค่าตาม key ที่ได้แต่ละรอบ — ทำงานร่วมกับ template literal ได้เช่นกัน
const user = {
name: "Alice",
age: 25,
role: "admin",
active: true,
};
for (const key in user) {
console.log(key + ": " + user[key]);
}
// "name: Alice"
// "age: 25"
// "role: admin"
// "active: true"for...in ให้ key ทีละรอบ — `obj[key]` ดึงค่าที่ผูกกับ key นั้น
for...in มีประโยชน์เมื่อไม่รู้ล่วงหน้าว่า object มี key อะไรบ้าง
เมื่อ object มาจาก config, API response, หรือ user input — ไม่รู้จำนวนและชื่อ key ล่วงหน้า `for...in` วนผ่านทุก key ได้โดยไม่ต้องระบุชื่อ property ทีละตัว
เพิ่มวิชาใหม่เข้า `scores` — for...in จะวนครบโดยอัตโนมัติ ไม่ต้องแก้โค้ด
const scores = {
math: 88,
science: 75,
english: 92,
history: 61,
};
let total = 0;
for (const subject in scores) {
total += scores[subject];
console.log(subject + ": " + scores[subject]);
}
console.log("รวม: " + total);
// "math: 88"
// "science: 75"
// "english: 92"
// "history: 61"
// "รวม: 316"ข้อควรระวัง — `for...in` อาจวน inherited property ได้ด้วย
ในงานทั่วไป `for...in` ช่วยวน key ของ object ได้ตรงไปตรงมา แต่มีข้อควรรู้เชิงปฏิบัติอยู่อย่างหนึ่ง: มันอาจพา property ที่สืบทอดมาจาก prototype มาด้วย ไม่ได้จำกัดแค่ property ของ object เองเสมอไป สำหรับผู้เริ่มต้น ให้จำเป็นกฎใช้งานง่าย ๆ ว่า ถ้าอยากคุมผลลัพธ์ให้ชัดและเอาเฉพาะ key ของ object เอง บทถัดไปอย่าง `Object.keys()` จะตรงกว่า
ถ้าต้องการเฉพาะ key ของ object เอง บท `Object.keys()` จะช่วยให้ผลลัพธ์คาดเดาง่ายกว่า
const parent = {
inheritedFlag: true,
};
const config = Object.create(parent);
config.theme = "dark";
config.language = "th";
for (const key in config) {
console.log(key);
}
// "theme"
// "language"
// "inheritedFlag"| โจทย์ | เครื่องมือที่เหมาะ | เหตุผล |
|---|---|---|
| อยากวน key ของ object โดยตรง | `for...in` | ได้ key ทีละตัวทันที |
| อยากได้เฉพาะ key ของ object เอง | `Object.keys()` | คุมผลลัพธ์ได้ชัดกว่า |
| อยากวน array ทีละค่า | `for...of` | ได้ element โดยตรง |
| อยากได้ index ของ array | `for` loop | มี `i` ให้ใช้ตลอด |
ถ้าอยากเห็นว่าทำไม `for...in` ไม่เหมาะกับ array จริง ๆ ให้ดูหน้าบท `for...in กับ array` ซึ่งจะแสดงให้เห็นว่า key ที่ได้เป็น string และชวนให้ arithmetic พลาดได้ง่าย