JavaScript
Object
Nested objects
เรียนรู้การสร้างและใช้งาน nested object ใน JavaScript ตั้งแต่การสร้าง object ซ้อน object, การเข้าถึงข้อมูลหลายชั้นด้วย dot chaining และ bracket chaining แบบ dynamic key, การเพิ่มและอัปเดตข้อมูลใน object ซ้อน ไปจนถึงการป้องกัน error เมื่อ path ระหว่างทางเป็น undefined
Nested Object คืออะไร — Object ซ้อน Object
Object ใน JavaScript สามารถเก็บ value ได้ทุกประเภท — รวมถึง object อีกตัว เมื่อ value ของ property เป็น object อีกตัวหนึ่ง เราเรียกสิ่งนั้นว่า **Nested Object** (object ซ้อน object) นี่คือรูปแบบที่พบได้ทั่วไปในข้อมูลที่ซับซ้อน เช่น ข้อมูลผู้ใช้ที่มีที่อยู่แยกเป็นบ้านเลขที่ ถนน เมือง หรือข้อมูลสินค้าที่มีรายละเอียดย่อยแยกออกมา
ค่า address เป็น object ซ้อนอยู่ใน user อีกชั้นหนึ่ง
const user = {
name: "สมชาย",
email: "somchai@email.com",
address: {
street: "สุขุมวิท 21",
district: "วัฒนา",
city: "กรุงเทพ",
zipcode: "10110",
},
};
console.log(user);
// {
// name: 'สมชาย',
// email: 'somchai@email.com',
// address: { street: 'สุขุมวิท 21', district: 'วัฒนา', city: 'กรุงเทพ', zipcode: '10110' }
// }• **user** เป็น object หลัก • **user.address** เป็น object ที่ซ้อนอยู่ข้างใน • address มี properties ของตัวเองอีก 4 ตัว วิธีคิดง่าย ๆ: มองเป็นโฟลเดอร์ซ้อนโฟลเดอร์ — user คือโฟลเดอร์หลัก, address คือโฟลเดอร์ย่อยที่อยู่ข้างใน
เข้าถึงข้อมูลใน Nested Object ด้วย Dot Chaining
การเข้าถึง property ของ object ซ้อน ทำได้โดยการเชื่อม (chain) dot notation หรือ bracket notation ต่อกันตามลำดับชั้น — เหมือนเดินเข้าไปทีละชั้นจนถึงข้อมูลที่ต้องการ
ใช้ dot notation ต่อกันเพื่อเข้าถึง property ตามลำดับชั้น
const book = {
title: "JavaScript พื้นฐาน",
author: {
name: "อาจารย์แดง",
email: "red@email.com",
},
};
// Dot chaining — อ่านค่าทีละชั้น
console.log(book.title); // "JavaScript พื้นฐาน"
console.log(book.author.name); // "อาจารย์แดง"
console.log(book.author.email); // "red@email.com"ใช้ bracket notation ต่อกันเมื่อต้องใช้ตัวแปรเป็น key
const book = {
title: "JavaScript พื้นฐาน",
author: { name: "อาจารย์แดง" },
publisher: { name: "สำนักพิมพ์เรียนรู้" },
};
// Bracket chaining — ใช้เมื่อ key มาจากตัวแปร
const role = "author";
const field = "name";
console.log(book[role][field]); // "อาจารย์แดง"
// ผสมกันก็ได้ — dot + bracket
console.log(book.author[field]); // "อาจารย์แดง"
console.log(book[role].name); // "อาจารย์แดง"| รูปแบบ | ตัวอย่าง | ใช้เมื่อ |
|---|---|---|
| Dot chaining | obj.a.b.c | รู้ชื่อ key ชัดเจนตั้งแต่เขียนโค้ด |
| Bracket chaining | obj["a"]["b"]["c"] | key มีอักขระพิเศษ หรือ key มาจากตัวแปร |
| ผสม dot + bracket | obj.a["b"].c | บาง key รู้ตายตัว บาง key เป็น dynamic |
เพิ่มและอัปเดตข้อมูลใน Nested Object
การเพิ่มหรือแก้ไข property ใน object ซ้อนใช้หลักการเดียวกับ object ปกติ — chain `.` หรือ `[]` ไปถึงตำแหน่งที่ต้องการแล้ว assign ค่า
ใช้ dot/bracket notation ต่อกันจนถึงตำแหน่งที่ต้องการ แล้ว assign ค่า
const user = {
name: "สมหญิง",
address: {
city: "กรุงเทพ",
},
};
// อัปเดตค่าใน object ซ้อน
user.address.city = "เชียงใหม่";
console.log(user.address.city); // "เชียงใหม่"
// เพิ่ม property ใหม่ใน object ซ้อน
user.address.zipcode = "50200";
user.address.district = "เมือง";
console.log(user.address);
// { city: 'เชียงใหม่', zipcode: '50200', district: 'เมือง' }
// เพิ่ม object ซ้อนใหม่ทั้งก้อน
user.settings = {
theme: "dark",
language: "th",
};
console.log(user.settings.theme); // "dark"**ข้อควรระวัง:** ถ้า object ระหว่างทางยังไม่มีอยู่ JavaScript จะเกิด error `Cannot set properties of undefined` เพราะ path ที่เราจะเข้าไปไม่มีอยู่จริง
ต้องแน่ใจว่า object ระหว่างทางมีอยู่ก่อนจึงจะเพิ่ม property ได้
const user = { name: "สมชาย" };
// ❌ TypeError: Cannot set properties of undefined
// user.address.city = "กรุงเทพ";
// เพราะ user.address ยังไม่ได้สร้าง!
// ✅ ต้องสร้าง object ระหว่างทางก่อน
user.address = {};
user.address.city = "กรุงเทพ";
console.log(user.address.city); // "กรุงเทพ"ข้อควรระวัง — Cannot read properties of undefined
เวลาอ่านค่า nested object สิ่งที่พบบ่อยที่สุดคือการพยายามเข้าถึง property ที่ไม่มีอยู่ ซึ่งทำให้เกิด error: `Cannot read properties of undefined` สาเหตุ: object ระหว่างทางใน chain เป็น `undefined` — หมายความว่า path นั้นไม่มีอยู่ JavaScript มี 2 วิธีหลักในการป้องกันด้วยความรู้ที่เรามีอยู่แล้ว:
ใช้ if หรือ logical operators เพื่อเช็คว่า object ระหว่างทางมีอยู่ก่อนเข้าถึง
const product = {
name: "กาแฟดำ",
// ไม่มี details
};
// ✅ product.name — มีอยู่ อ่านได้ปกติ
console.log(product.name); // "กาแฟดำ"
// วิธีที่ 1 — เช็คทีละชั้นด้วย if
if (product.details) {
console.log(product.details.weight);
// ในที่นี้จะไม่เข้า เพราะ product.details เป็น undefined
}
// วิธีที่ 2 — ใช้ && เป็น guard
const weight = product.details && product.details.weight;
console.log(weight); // undefined (ไม่เกิด error)| วิธี | โค้ด | ข้อดี | ข้อควรระวัง |
|---|---|---|---|
| if เช็คทีละชั้น | if (obj.a) { ... } | อ่านเข้าใจง่าย | ชั้นลึกมาก ๆ จะยาว |
| && guard | obj.a && obj.a.b | สั้นกว่า if | อ่านลำบากถ้าชั้นเยอะ |
ในบทถัด ๆ ไป JavaScript ยังมี Optional Chaining (`?.`) ซึ่งเขียนสั้นกว่า — `obj.a?.b?.c` — แต่เราควรเข้าใจการเช็คด้วย `if` และ `&&` ให้แม่นก่อน เพราะเป็นพื้นฐานที่ใช้ได้กับ JavaScript ทุกเวอร์ชัน
ตัวอย่างจริง — ข้อมูลสินค้าที่มีโครงสร้างซับซ้อน
ตัวอย่าง object สินค้าที่มีรายละเอียดซ้อนกันหลายชั้น เหมือนข้อมูลที่มาจาก API จริง
const product = {
id: "P001",
name: "เมล็ดกาแฟคั่วกลาง",
price: 350,
details: {
weight: 250,
unit: "g",
origin: {
country: "ไทย",
region: "เชียงราย",
farm: "ดอยช้าง",
},
roast: {
level: "medium",
date: "2025-04-01",
},
},
stock: {
available: true,
quantity: 120,
},
};
// เข้าถึงข้อมูลหลายชั้น
console.log(product.details.origin.country); // "ไทย"
console.log(product.details.roast.level); // "medium"
console.log(product.stock.quantity); // 120
// อ่าน origin ทั้งก้อน
const origin = product.details.origin;
console.log(origin);
// { country: 'ไทย', region: 'เชียงราย', farm: 'ดอยช้าง' }จะเห็นว่า nested object ทำให้เราจัดกลุ่มข้อมูลที่เกี่ยวข้องกันไว้ด้วยกันอย่างเป็นธรรมชาติ — origin รวมข้อมูลแหล่งปลูก, roast รวมข้อมูลการคั่ว, stock รวมข้อมูลสต็อก