JavaScript
Loop Arrays & Objects
Object.keys()
เรียนรู้ว่า `Object.keys()` คืน array ของชื่อ key แล้วนำไปวนต่อด้วย `for` หรือ `for...of` เพื่อเตรียมทางไปสู่การวน object แบบที่คุมผลลัพธ์ได้ง่ายขึ้น
`Object.keys()` คืออะไร — คืน array ของชื่อ key ที่ object มีอยู่
`Object.keys(obj)` รับ object แล้วคืน **array ของชื่อ key** ทั้งหมดที่ object นั้นมีอยู่ จุดสำคัญคือผลลัพธ์เป็น array ทันที จึงใช้ `for` loop, `for...of`, `.length` และการเข้าถึงด้วย index ต่อได้เลย
ตัวอย่างแรกตั้งใจให้เห็นก่อนว่า `Object.keys()` ไม่ได้คืน object ใหม่ แต่คืน array ของ string
const user = {
name: "Alice",
age: 25,
role: "admin",
active: true,
};
const keys = Object.keys(user);
console.log(keys); // ["name", "age", "role", "active"]
console.log(keys.length); // 4
console.log(keys[0]); // "name"`Object.keys(obj)` ดึงเฉพาะชื่อ key ออกมา แล้วเก็บเป็น array เพื่อให้วนลูปหรือใช้ index ได้
ใช้ `Object.keys()` กับ `for` loop เมื่ออยากได้ index
เมื่อผลลัพธ์เป็น array เราจึงใช้ `for` loop แบบเดิมได้ทันที วิธีนี้เหมาะเมื่อคุณต้องการทั้ง `index` และ `key` ในรอบเดียว เช่น แสดงลำดับข้อหรือใช้ `keys[i]` ไปอ่านค่าจาก object เดิม
`keys[i]` คือชื่อ key ส่วน `user[key]` คือค่าที่เก็บอยู่ใน key นั้น
const user = {
name: "Alice",
age: 25,
role: "admin",
active: true,
};
const keys = Object.keys(user);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
console.log(i + ": " + key + " = " + user[key]);
}
// "0: name = Alice"
// "1: age = 25"
// "2: role = admin"
// "3: active = true"รูปแบบนี้ยังใช้กับงานสะสมค่าได้ด้วย เช่น รวมคะแนนทุกวิชา เพราะเรายังเข้าถึง `scores[key]` ได้เหมือนเดิม
ใช้ `Object.keys()` ร่วมกับ accumulator pattern ได้เหมือนการวน object แบบอื่น
const scores = {
math: 88,
science: 75,
english: 92,
history: 61,
};
const subjects = Object.keys(scores);
let total = 0;
for (let i = 0; i < subjects.length; i++) {
total += scores[subjects[i]];
}
console.log(total); // 316ใช้ `Object.keys()` กับ `for...of` เมื่ออยากวน key แบบกระชับ
ถ้าไม่ต้องใช้ index ให้ใช้ `for...of` วน array ของ key ได้ตรงกว่า อ่านง่ายกว่า และลดตัวแปรที่ต้องจัดการเอง
`for...of` ใช้กับ array จาก `Object.keys()` ได้ทันที จึงเหมาะกับงานที่ต้องอ่าน key ทีละตัวโดยไม่สนลำดับ index
const settings = {
darkMode: true,
autoSave: true,
notifications: false,
};
for (const key of Object.keys(settings)) {
console.log(key + ": " + settings[key]);
}
// "darkMode: true"
// "autoSave: true"
// "notifications: false"- `for...in` เหมาะเมื่ออยากวน key ของ object โดยตรง
- `Object.keys()` + `for` เหมาะเมื่ออยากได้ index เพิ่ม
- `Object.keys()` + `for...of` เหมาะเมื่ออยากให้โค้ดสั้นและอ่านง่าย
`Object.keys()` ต่างจาก `for...in` ตรง inherited property
จุดต่างสำคัญคือ `Object.keys()` คืนเฉพาะ property ที่ object เป็นเจ้าของเอง ส่วน `for...in` อาจวน property ที่สืบทอดจาก prototype มาด้วย สำหรับผู้เริ่มต้น เรื่องนี้ช่วยให้เข้าใจว่าทำไมหลายครั้ง `Object.keys()` จึงปลอดภัยและคาดเดาง่ายกว่า
`Object.keys(child)` ไม่รวม `parentMethod` แต่ `for...in` วนไปถึง property ที่สืบทอดมา
const parent = {
parentMethod: function () {},
};
const child = Object.create(parent);
child.name = "Bob";
child.score = 90;
console.log(Object.keys(child));
// ["name", "score"]
for (const key in child) {
console.log(key);
}
// "name"
// "score"
// "parentMethod"| หัวข้อ | Object.keys() | for...in |
|---|---|---|
| ผลลัพธ์ | array ของ key | วน key ได้ทันที |
| ได้ index ไหม | ได้ ผ่าน array | ไม่ได้โดยตรง |
| รวม inherited property ไหม | ไม่รวม | อาจรวม |
| เหมาะเมื่อ | อยากได้ array หรืออยากคุมผลลัพธ์ | อยากวน key ของ object โดยตรง |
ข้อผิดพลาดที่พบบ่อยกับ `Object.keys()`
- **เขียน `obj.keys()` แทน `Object.keys(obj)`** — `Object.keys` เป็น static method เรียกผ่าน `Object` ไม่ได้เรียกผ่าน object ตัวนั้น
- **ใช้ `for...of` กับ object ตรง ๆ** — `for (const key of user)` จะ error เพราะ object ไม่ใช่ iterable
- **คิดว่าแก้ array ที่ได้แล้ว object เดิมจะเปลี่ยนตาม** — array จาก `Object.keys()` เป็นผลลัพธ์ใหม่ ไม่ได้ผูกกับ object ต้นฉบับ
จำง่าย ๆ: `Object.keys(obj)` คืน array แล้วค่อยนำ array นั้นไปวนต่อ
const user = { name: "Alice", age: 25 };
// ❌ ผิด
// user.keys();
// ✅ ถูก
const keys = Object.keys(user);
console.log(keys); // ["name", "age"]
// ❌ ผิด
// for (const key of user) {}
// ✅ ถูก
for (const key of Object.keys(user)) {
console.log(key);
}ต่อยอดจากบทนี้ไป `for...of` กับ object
สิ่งสำคัญของบทนี้คือการเห็นว่า `Object.keys()` คืน array กลับมา เมื่อได้ array แล้วเราก็ใช้ `for...of` วน key เหล่านั้นได้ทันที บท `for...of กับ object` จะพาคุณเลือกให้ชัดว่าเมื่อไหร่ควรใช้ `Object.keys()`, `Object.values()`, หรือ `Object.entries()` ก่อนค่อยวนด้วย `for...of`