# สัปดาห์ที่ 6: Objects & Arrays (อ็อบเจกต์และอาร์เรย์)

## 📚 สารบัญ

1. [Arrays (อาร์เรย์)](#arrays)
2. [Objects (อ็อบเจกต์)](#objects)
3. [การทำงานกับ Arrays](#array-methods)
4. [การทำงานกับ Objects](#object-methods)
5. [Array of Objects](#array-of-objects)
6. [แบบฝึกหัด](#exercises)

---

## Arrays (อาร์เรย์) {#arrays}

### คำอธิบาย

อาร์เรย์ (Array) เป็นหนึ่งในโครงสร้างข้อมูลที่สำคัญที่สุดในการเขียนโปรแกรม มันช่วยให้เราสามารถ:

- เก็บค่าหลายค่าในตัวแปรเดียว
- เข้าถึงค่าต่างๆ ด้วย index (ตำแหน่ง)
- ทำงานกับชุดข้อมูลขนาดใหญ่ได้อย่างมีประสิทธิภาพ
- ใช้ array methods เพื่อแปลง กรอง และประมวลผลข้อมูล

การเข้าใจ arrays เป็นพื้นฐานสำคัญสำหรับการเขียน JavaScript ที่มีประสิทธิภาพ

### คืออะไร?

อาร์เรย์เป็นคอลเล็กชันที่เก็บค่าหลายค่าในตัวแปรเดียว ซึ่งเป็นประเภทข้อมูลที่สำคัญมากในการเขียนโปรแกรม

### การสร้างอาร์เรย์

#### 1. ใช้ Array Literals (วิธีทั่วไป)

```javascript
// อาร์เรย์ว่าง
const emptyArray = [];

// อาร์เรย์ที่มีตัวเลข
const numbers = [10, 20, 30, 40, 50];

// อาร์เรย์ที่มีข้อความ
const fruits = ["apple", "banana", "orange", "mango"];

// อาร์เรย์แบบผสม (mixed types)
const mixed = [1, "hello", true, 3.14];

// อาร์เรย์ซ้อน (nested array)
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];
```

#### 2. ใช้ Array Constructor

```javascript
// สร้างอาร์เรย์ที่มีขนาดกำหนด
const arr = new Array(5); // [empty × 5]

// ไม่ถูกสร้างจาก constructor มากนักเพราะสับสน
```

### การเข้าถึงองค์ประกอบในอาร์เรย์

```javascript
const fruits = ["apple", "banana", "orange"];

// เข้าถึงด้วยตัวเลข index (เริ่มจาก 0)
console.log(fruits[0]); // 'apple'
console.log(fruits[1]); // 'banana'
console.log(fruits[2]); // 'orange'
console.log(fruits[10]); // undefined (ไม่มีอยู่)

// เปลี่ยนค่าในอาร์เรย์
fruits[1] = "blueberry";
console.log(fruits); // ['apple', 'blueberry', 'orange']

// ความยาวของอาร์เรย์
console.log(fruits.length); // 3
```

### Loop ผ่านอาร์เรย์

#### 1. for loop

```javascript
const fruits = ["apple", "banana", "orange"];

for (let i = 0; i < fruits.length; i++) {
  console.log(i + ": " + fruits[i]);
}
// ผลลัพธ์:
// 0: apple
// 1: banana
// 2: orange
```

#### 2. forEach method

```javascript
const fruits = ["apple", "banana", "orange"];

fruits.forEach((fruit, index) => {
  console.log(index + ": " + fruit);
});

// หรือใช้ function ธรรมดา
fruits.forEach(function (fruit, index) {
  console.log(index + ": " + fruit);
});
```

#### 3. for...of loop

```javascript
const fruits = ["apple", "banana", "orange"];

for (let fruit of fruits) {
  console.log(fruit);
}
// ผลลัพธ์:
// apple
// banana
// orange
```

---

## Objects (อ็อบเจกต์) {#objects}

### คำอธิบาย

Objects (อ็อบเจกต์) เป็นโครงสร้างข้อมูลที่ยืดหยุ่นมากสำหรับการจัดเก็บข้อมูลที่เกี่ยวข้องกัน Objects ช่วยให้:

- จัดกลุ่มข้อมูล properties ที่เกี่ยวข้องเข้าด้วยกัน
- สร้าง template สำหรับสิ่งต่างๆ ในโลกจริง (เช่น person, product, car ฯลฯ)
- เก็บทั้งข้อมูล (properties) และ behaviors (methods) ในสถานที่เดียว
- สร้าง organized structure ที่ทำให้ code อ่านง่ายและดูแลง่าย
- เป็นพื้นฐานสำหรับ Object-Oriented Programming (OOP)

Objects เป็นจุดเริ่มต้นของการเข้าใจ OOP และหลายของ JavaScript patterns ขั้นสูง

### คืออะไร?

อ็อบเจกต์เป็นคอลเล็กชันของคู่ key-value ที่เก็บข้อมูลและฟังก์ชัน เหมาะสำหรับการจัดกลุ่มข้อมูลที่เกี่ยวข้องกัน

### การสร้างอ็อบเจกต์

#### 1. Object Literals (วิธีทั่วไป)

```javascript
// อ็อบเจกต์ว่าง
const emptyObj = {};

// อ็อบเจกต์ที่มีคุณสมบัติ
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
  isStudent: true,
};

// อ็อบเจกต์ที่มีวิธีการ (method)
const student = {
  name: "สมชาย",
  age: 20,
  greet: function () {
    console.log("สวัสดีค่ะ ฉันชื่อ " + this.name);
  },
};

// เรียกใช้ method
student.greet(); // สวัสดีค่ะ ฉันชื่อ สมชาย
```

#### 2. Object Constructor

```javascript
// สร้างอ็อบเจกต์ว่างก่อน
const person = new Object();

// เพิ่มคุณสมบัติ
person.name = "สมชาย";
person.age = 25;
person.email = "somchai@example.com";
```

#### 3. Constructor Function

```javascript
// ฟังก์ชัน constructor (ประเพณีใช้ตัวอักษรตัวใหญ่เริ่มต้น)
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.introduce = function () {
    console.log("ชื่อ: " + this.name + ", อายุ: " + this.age);
  };
}

// สร้าง instance
const person1 = new Person("สมชาย", 25);
const person2 = new Person("จิตรา", 23);

person1.introduce(); // ชื่อ: สมชาย, อายุ: 25
person2.introduce(); // ชื่อ: จิตรา, อายุ: 23
```

### การเข้าถึงคุณสมบัติในอ็อบเจกต์

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

// 1. Dot notation (ต้องใช้ชื่อที่ถูกต้องตามตัวแปร)
console.log(person.name); // 'สมชาย'
console.log(person.age); // 25

// 2. Bracket notation (สามารถใช้ชื่อที่มีเครื่องหมายพิเศษได้)
console.log(person["name"]); // 'สมชาย'
console.log(person["age"]); // 25

// 3. เปลี่ยนค่าคุณสมบัติ
person.age = 26;
person["email"] = "newmail@example.com";
console.log(person); // { name: 'สมชาย', age: 26, email: 'newmail@example.com' }

// 4. เพิ่มคุณสมบัติใหม่
person.phone = "08-1234-5678";
console.log(person.phone); // '08-1234-5678'

// 5. ลบคุณสมบัติ
delete person.phone;
```

### Loop ผ่านอ็อบเจกต์

#### 1. for...in loop

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

for (let key in person) {
  console.log(key + ": " + person[key]);
}
// ผลลัพธ์:
// name: สมชาย
// age: 25
// email: somchai@example.com
```

#### 2. Object.keys() + forEach

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

const keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'email']

keys.forEach((key) => {
  console.log(key + ": " + person[key]);
});
```

#### 3. Object.entries()

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

Object.entries(person).forEach(([key, value]) => {
  console.log(key + ": " + value);
});
```

#### 4. Object.values()

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

const values = Object.values(person);
console.log(values); // ['สมชาย', 25, 'somchai@example.com']
```

---

## Array Methods (เมธอดของอาร์เรย์) {#array-methods}

### คำอธิบาย

Array Methods คือ functions ที่เขียนมาให้พร้อมสำหรับ arrays ซึ่งช่วยให้:

- เปลี่ยนแปลงเนื้อหาของ arrays (add, remove, modify)
- ค้นหาและกรองข้อมูล (find, filter, search)
- แปลง arrays เป็นรูปแบบต่างๆ (map, reduce, transform)
- วนลูปผ่าน arrays (forEach, map)
- รวมหรือแยก arrays (concat, slice, split)

การเข้าใจ array methods ช่วยลดการเขียน code ซ้ำๆ และทำให้ code concise มากขึ้น

### การเปลี่ยนแปลงอาร์เรย์

#### 1. push() - เพิ่มที่ท้าย

```javascript
const fruits = ["apple", "banana"];

fruits.push("orange");
console.log(fruits); // ['apple', 'banana', 'orange']

// สามารถเพิ่มหลายค่าพร้อมกัน
fruits.push("grape", "mango");
console.log(fruits); // ['apple', 'banana', 'orange', 'grape', 'mango']
```

#### 2. pop() - ลบที่ท้าย

```javascript
const fruits = ["apple", "banana", "orange"];

const removed = fruits.pop();
console.log(removed); // 'orange'
console.log(fruits); // ['apple', 'banana']
```

#### 3. unshift() - เพิ่มที่หน้า

```javascript
const fruits = ["apple", "banana"];

fruits.unshift("grape");
console.log(fruits); // ['grape', 'apple', 'banana']
```

#### 4. shift() - ลบที่หน้า

```javascript
const fruits = ["apple", "banana", "orange"];

const removed = fruits.shift();
console.log(removed); // 'apple'
console.log(fruits); // ['banana', 'orange']
```

#### 5. splice() - เพิ่ม/ลบ/เปลี่ยนค่า

```javascript
const fruits = ["apple", "banana", "orange"];

// ลบ 1 องค์ประกอบที่ index 1
fruits.splice(1, 1);
console.log(fruits); // ['apple', 'orange']

// เพิ่ม 'grape' ที่ index 1
fruits.splice(1, 0, "grape");
console.log(fruits); // ['apple', 'grape', 'orange']

// เปลี่ยน 'grape' เป็น 'blueberry' และ 'orange' เป็น 'mango'
fruits.splice(1, 2, "blueberry", "mango");
console.log(fruits); // ['apple', 'blueberry', 'mango']
```

### การค้นหาและกรอง

#### 1. indexOf() - หาตำแหน่งแรก

```javascript
const fruits = ["apple", "banana", "orange", "banana"];

console.log(fruits.indexOf("banana")); // 1
console.log(fruits.indexOf("grape")); // -1 (ไม่พบ)
console.log(fruits.indexOf("banana", 2)); // 3 (หาจากตำแหน่ง 2)
```

#### 2. includes() - ตรวจสอบการมีอยู่

```javascript
const fruits = ["apple", "banana", "orange"];

console.log(fruits.includes("banana")); // true
console.log(fruits.includes("grape")); // false
```

#### 3. find() - หา 1 องค์ประกอบตามเงื่อนไข

```javascript
const numbers = [5, 10, 15, 20, 25];

const found = numbers.find((num) => num > 15);
console.log(found); // 20

const users = [
  { id: 1, name: "สมชาย" },
  { id: 2, name: "จิตรา" },
  { id: 3, name: "นัทสยา" },
];

const user = users.find((u) => u.id === 2);
console.log(user); // { id: 2, name: 'จิตรา' }
```

#### 4. filter() - กรองหลายองค์ประกอบ

```javascript
const numbers = [5, 10, 15, 20, 25];

const evens = numbers.filter((num) => num % 2 === 0);
console.log(evens); // [10, 20]

const users = [
  { id: 1, name: "สมชาย", age: 25 },
  { id: 2, name: "จิตรา", age: 20 },
  { id: 3, name: "นัทสยา", age: 23 },
];

const adults = users.filter((u) => u.age >= 21);
console.log(adults); // สองคนแรก
```

#### 5. some() - ตรวจสอบ บางองค์ประกอบตรงตามเงื่อนไข

```javascript
const numbers = [5, 10, 15, 20, 25];

const hasEven = numbers.some((num) => num % 2 === 0);
console.log(hasEven); // true

const hasOver100 = numbers.some((num) => num > 100);
console.log(hasOver100); // false
```

#### 6. every() - ตรวจสอบ ทุกองค์ประกอบตรงตามเงื่อนไข

```javascript
const numbers = [5, 10, 15, 20, 25];

const allPositive = numbers.every((num) => num > 0);
console.log(allPositive); // true

const allLessThan15 = numbers.every((num) => num < 15);
console.log(allLessThan15); // false
```

### การแปลงอาร์เรย์

#### 1. map() - แปลงแต่ละองค์ประกอบ

```javascript
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map((num) => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

const users = [
  { id: 1, name: "สมชาย" },
  { id: 2, name: "จิตรา" },
  { id: 3, name: "นัทสยา" },
];

const names = users.map((u) => u.name);
console.log(names); // ['สมชาย', 'จิตรา', 'นัทสยา']
```

#### 2. reduce() - รวมเป็นค่าเดียว

```javascript
const numbers = [1, 2, 3, 4, 5];

// หาผลรวม
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

// หาผลคูณ
const product = numbers.reduce((acc, num) => acc * num, 1);
console.log(product); // 120

// นับจำนวน
const users = [
  { name: "สมชาย", role: "admin" },
  { name: "จิตรา", role: "user" },
  { name: "นัทสยา", role: "user" },
];

const countByRole = users.reduce((acc, user) => {
  if (acc[user.role]) {
    acc[user.role]++;
  } else {
    acc[user.role] = 1;
  }
  return acc;
}, {});

console.log(countByRole); // { admin: 1, user: 2 }
```

#### 3. join() - รวมเป็นข้อความ

```javascript
const fruits = ["apple", "banana", "orange"];

console.log(fruits.join(", ")); // 'apple, banana, orange'
console.log(fruits.join(" | ")); // 'apple | banana | orange'
console.log(fruits.join("")); // 'applebananaorange'
```

#### 4. reverse() - กลับลำดับ

```javascript
const fruits = ["apple", "banana", "orange"];

fruits.reverse();
console.log(fruits); // ['orange', 'banana', 'apple']
```

#### 5. sort() - เรียงลำดับ

```javascript
const fruits = ["orange", "apple", "banana"];

fruits.sort();
console.log(fruits); // ['apple', 'banana', 'orange']

const numbers = [5, 20, 3, 1, 15];

// เรียงตัวเลขจากน้อยไปมาก
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 3, 5, 15, 20]

// เรียงตัวเลขจากมากไปน้อย
numbers.sort((a, b) => b - a);
console.log(numbers); // [20, 15, 5, 3, 1]
```

#### 6. slice() - สก็อปหลายองค์ประกอบ

```javascript
const fruits = ["apple", "banana", "orange", "grape"];

console.log(fruits.slice(1, 3)); // ['banana', 'orange']
console.log(fruits.slice(2)); // ['orange', 'grape']
console.log(fruits.slice(-2)); // ['orange', 'grape']
console.log(fruits.slice(0)); // ['apple', 'banana', 'orange', 'grape'] (copy)
```

#### 7. concat() - รวมอาร์เรย์

```javascript
const arr1 = ["apple", "banana"];
const arr2 = ["orange", "grape"];

const combined = arr1.concat(arr2);
console.log(combined); // ['apple', 'banana', 'orange', 'grape']

const combined2 = arr1.concat(arr2, ["mango"]);
console.log(combined2); // ['apple', 'banana', 'orange', 'grape', 'mango']

// แบบ spread operator
const combined3 = [...arr1, ...arr2];
console.log(combined3); // ['apple', 'banana', 'orange', 'grape']
```

---

## Object Methods (เมธอดของอ็อบเจกต์) {#object-methods}

### คำอธิบาย

Object Methods คือ static methods ที่ใช้กับ Object ทั้งหมด เพื่อ:

- ดึง keys, values, หรือ key-value pairs จาก objects
- รวม objects หลายตัวเข้าด้วยกัน
- ตรวจสอบว่า property มีอยู่ใน object หรือไม่
- Clone หรือ copy objects
- Freeze หรือ seal objects เพื่อป้องกันการแก้ไข

Object methods มีประโยชน์มากในการทำงานกับ objects อย่างปลอดภัยและมีประสิทธิภาพ

### Object.keys() - ดึงชื่อ property ทั้งหมด

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

const keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'email']
```

### Object.values() - ดึงค่า property ทั้งหมด

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

const values = Object.values(person);
console.log(values); // ['สมชาย', 25, 'somchai@example.com']
```

### Object.entries() - ดึง key-value pair ทั้งหมด

```javascript
const person = {
  name: "สมชาย",
  age: 25,
  email: "somchai@example.com",
};

const entries = Object.entries(person);
console.log(entries);
// [
//   ['name', 'สมชาย'],
//   ['age', 25],
//   ['email', 'somchai@example.com']
// ]
```

### Object.assign() - คัดลอกหรือรวม object

```javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };

// รวม obj2 เข้า obj1
const merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: 3, c: 4 }

// หรือใช้ spread operator
const merged2 = { ...obj1, ...obj2 };
console.log(merged2); // { a: 1, b: 3, c: 4 }
```

### Object.hasOwnProperty() - ตรวจสอบ property มีอยู่หรือไม่

```javascript
const person = {
  name: "สมชาย",
  age: 25,
};

console.log(person.hasOwnProperty("name")); // true
console.log(person.hasOwnProperty("email")); // false
console.log("name" in person); // true (อีกวิธี)
```

---

## Array of Objects (อาร์เรย์ของอ็อบเจกต์) {#array-of-objects}

### คำอธิบาย

Array of Objects เป็น pattern ที่นิยมใช้มากในการจัดการข้อมูล เพราะว่า:

- สามารถเก็บชุดข้อมูล (dataset) ได้ เช่น list of users, list of products
- สามารถใช้ array methods เพื่อค้นหา กรอง เรียงลำดับ ข้อมูล
- เป็นโครงสร้างที่คล้ายกับ database tables
- ทำให้ code readable และ maintainable มากขึ้น

ตัวอย่างเช่น API จากเซิร์ฟเวอร์ส่งมาข้อมูลเป็น array of objects เป็นปกติ ดังนั้นการเข้าใจและใช้งาน array of objects จึงมีความสำคัญมาก

### การสร้างและเข้าถึง

```javascript
const students = [
  { id: 1, name: "สมชาย", grade: "A", score: 95 },
  { id: 2, name: "จิตรา", grade: "B", score: 85 },
  { id: 3, name: "นัทสยา", grade: "A", score: 92 },
];

// เข้าถึง element ของอ็อบเจกต์
console.log(students[0].name); // 'สมชาย'
console.log(students[1].score); // 85

// วนลูป
students.forEach((student) => {
  console.log(student.name + ": " + student.score);
});
// ผลลัพธ์:
// สมชาย: 95
// จิตรา: 85
// นัทสยา: 92
```

### ตัวอย่างการใช้งานจริง

```javascript
// ข้อมูลเดือน
const expenses = [
  { date: "2024-01-01", category: "อาหาร", amount: 150 },
  { date: "2024-01-02", category: "ยา", amount: 200 },
  { date: "2024-01-03", category: "อาหาร", amount: 100 },
  { date: "2024-01-04", category: "ขนส่ง", amount: 50 },
  { date: "2024-01-05", category: "อาหาร", amount: 120 },
];

// ค้นหาค่าใช้จ่ายสำหรับอาหาร
const foodExpenses = expenses.filter((e) => e.category === "อาหาร");
console.log(foodExpenses);
// [
//   { date: '2024-01-01', category: 'อาหาร', amount: 150 },
//   { date: '2024-01-03', category: 'อาหาร', amount: 100 },
//   { date: '2024-01-05', category: 'อาหาร', amount: 120 }
// ]

// รวมค่าใช้จ่ายทั้งหมด
const totalExpense = expenses.reduce((sum, e) => sum + e.amount, 0);
console.log(totalExpense); // 620

// รวมค่าใช้จ่ายตามหมวด
const byCategory = expenses.reduce((acc, e) => {
  if (acc[e.category]) {
    acc[e.category] += e.amount;
  } else {
    acc[e.category] = e.amount;
  }
  return acc;
}, {});

console.log(byCategory);
// { อาหาร: 370, ยา: 200, ขนส่ง: 50 }
```

---

## การสร้างฟังก์ชันที่มีประโยชน์

### คำอธิบาย

ส่วนนี้แสดงตัวอย่างของการสร้าง utility functions ที่นำ concepts ของ arrays, objects, และ functions มารวมกัน Utility functions เหล่านี้:

- ช่วยลดความซ้ำซ้อนในการเขียน code
- เป็น helper functions ที่สามารถนำมาใช้ซ้ำได้หลายครั้ง
- ทำให้ code เรียบร้อยและประหยัด
- เป็นตัวอย่างของการคิด programmatically

### ฟังก์ชันหาค่าเฉลี่ย

```javascript
function calculateAverage(numbers) {
  if (numbers.length === 0) return 0;

  const sum = numbers.reduce((acc, num) => acc + num, 0);
  return sum / numbers.length;
}

console.log(calculateAverage([10, 20, 30])); // 20
console.log(calculateAverage([95, 85, 92])); // 90.67
```

### ฟังก์ชันหาคนที่มีอายุมากที่สุด

```javascript
function findOldest(users) {
  return users.reduce((oldest, user) => {
    return user.age > oldest.age ? user : oldest;
  });
}

const people = [
  { name: "สมชาย", age: 25 },
  { name: "จิตรา", age: 30 },
  { name: "นัทสยา", age: 28 },
];

console.log(findOldest(people)); // { name: 'จิตรา', age: 30 }
```

### ฟังก์ชันจัดกลุ่มข้อมูล

```javascript
function groupBy(array, key) {
  return array.reduce((acc, item) => {
    const groupKey = item[key];
    if (!acc[groupKey]) {
      acc[groupKey] = [];
    }
    acc[groupKey].push(item);
    return acc;
  }, {});
}

const students = [
  { name: "สมชาย", grade: "A" },
  { name: "จิตรา", grade: "B" },
  { name: "นัทสยา", grade: "A" },
  { name: "สจ", grade: "B" },
];

const byGrade = groupBy(students, "grade");
console.log(byGrade);
// {
//   A: [{ name: 'สมชาย', grade: 'A' }, { name: 'นัทสยา', grade: 'A' }],
//   B: [{ name: 'จิตรา', grade: 'B' }, { name: 'สจ', grade: 'B' }]
// }
```

---

## ข้อเตือน และ Best Practices

### คำอธิบาย

ส่วนนี้สำคัญมากเพราะแสดงให้เห็น pitfalls ทั่วไปและวิธีหลีกเลี่ยงมัน:

- **Reference Type** - Arrays และ Objects เป็น reference type ที่อาจทำให้เกิด unexpected behaviors
- **Immutable vs Mutable** - บางเวลาการเปลี่ยนแปลงต้นฉบับอาจไม่ต้องการ
- **Performance** - บางวิธีเร็วกว่า บางวิธีช้า
- **Code Safety** - การเลือก methods ที่ถูกต้องช่วยให้ code ปลอดภัย

ความเข้าใจเรื่องนี้ช่วยให้เป็น experienced developer ที่สามารถหลีกเลี่ยง bugs ที่ยากต่อการแก้ไข

### 1. Arrays เป็น Reference Type

```javascript
const arr1 = [1, 2, 3];
const arr2 = arr1; // ชี้ไปยังอาร์เรย์เดียวกัน

arr2.push(4);
console.log(arr1); // [1, 2, 3, 4] - arr1 เปลี่ยนด้วย

// สำเร็จสำเร็จ copy ให้ใช้:
const arr3 = [...arr1]; // spread operator
const arr4 = arr1.slice(); // slice method
const arr5 = arr1.concat(); // concat method

arr3.push(5);
console.log(arr1); // [1, 2, 3, 4] - arr1 ไม่เปลี่ยน
```

### 2. Objects เป็น Reference Type

```javascript
const obj1 = { name: "สมชาย" };
const obj2 = obj1; // ชี้ไปยังอ็อบเจกต์เดียวกัน

obj2.name = "จิตรา";
console.log(obj1.name); // 'จิตรา' - obj1 เปลี่ยนด้วย

// Shallow copy
const obj3 = { ...obj1 };
const obj4 = Object.assign({}, obj1);

obj3.name = "นัทสยา";
console.log(obj1.name); // 'จิตรา' - obj1 ไม่เปลี่ยน
```

### 3. ระวังการเปลี่ยนแปลงอาร์เรย์

```javascript
const arr = [1, 2, 3, 4, 5];

// Methods ที่เปลี่ยนแปลงอาร์เรย์ต้นฉบับ
arr.push(6); // mutates
arr.pop(); // mutates
arr.reverse(); // mutates
arr.sort(); // mutates
arr.splice(0, 1); // mutates

// Methods ที่ไม่เปลี่ยนแปลง (return ใหม่)
arr.map((x) => x * 2); // immutable
arr.filter((x) => x > 2); // immutable
arr.slice(1, 3); // immutable
arr.concat([6, 7]); // immutable
```

### 4. ใช้ const สำหรับ arrays และ objects

```javascript
// ใช้ const แม้ว่าจะเปลี่ยนแปลง content
const arr = [];
arr.push(1); // OK

const obj = {};
obj.name = "สมชาย"; // OK

// แต่ไม่สามารถ reassign ได้
// arr = [1, 2, 3];  // Error
// obj = {};         // Error
```

---

## แบบฝึกหัด {#exercises}

### คำอธิบาย

แบบฝึกหัดเหล่านี้ออกแบบมาเพื่อให้:

- ฝึกปฏิบัติสิ่งที่เรียนรู้มา
- เพิ่มความเข้าใจผ่านการ hands-on coding
- สร้างความมั่นใจในการใช้งาน arrays และ objects
- ค่อยๆ ก้าวไปยัง problems ที่ซับซ้อนขึ้น (Easy → Medium → Hard)

### ระดับ Easy

#### 1. สร้างอาร์เรย์ของตัวเลข

```javascript
// สร้างอาร์เรย์ของตัวเลข 1 ถึง 10
// แล้วแสดงเฉพาะตัวเลขที่เป็นจำนวนคู่
```

#### 2. สร้างอ็อบเจกต์ของหนังสือ

```javascript
// สร้างอ็อบเจกต์ที่มี property: title, author, year, price
// แสดง property ทั้งหมด
```

#### 3. หาตัวเลขสูงสุดและต่ำสุด

```javascript
// สร้างฟังก์ชันที่หาตัวเลขสูงสุดและต่ำสุดจากอาร์เรย์
```

### ระดับ Medium

#### 4. ลดความซ้ำซ้อนในอาร์เรย์

```javascript
// สร้างฟังก์ชันที่ลบค่าที่ซ้ำกันออกจากอาร์เรย์
// ตัวอย่าง: [1, 2, 2, 3, 3, 3] -> [1, 2, 3]
```

#### 5. จัดเรียงอ็อบเจกต์

```javascript
// สร้างอาร์เรย์ของนักเรียน (ชื่อ, อายุ, คะแนน)
// จัดเรียงตามคะแนนจากมากไปน้อย
```

#### 6. คำนวณสถิติ

```javascript
// สร้างฟังก์ชันที่คำนวณ:
// - ผลรวม
// - ค่าเฉลี่ย
// - ค่ามัธยฐาน
// - ค่าเบี่ยงเบนมาตรฐาน
```

### ระดับ Hard

#### 7. สร้าง Shopping Cart

```javascript
// สร้าง object array ของสินค้า (id, name, price, quantity)
// ฟังก์ชันเพิ่มสินค้า
// ฟังก์ชันลบสินค้า
// ฟังก์ชันคำนวณราคารวม
// ฟังก์ชันหาสินค้าแพงที่สุด
```

#### 8. สร้างระบบ TODO List

```javascript
// ฟังก์ชันเพิ่ม TODO (id, task, completed, dueDate)
// ฟังก์ชันทำเครื่องหมายเสร็จสิ้น
// ฟังก์ชันลบ TODO
// ฟังก์ชันแสดง TODO ที่ยังไม่เสร็จ
// ฟังก์ชันแสดง TODO ตามวันครบกำหนด
```

---

## สรุป

- **Arrays** เก็บค่าหลายค่าในตัวแปรเดียว เข้าถึงด้วย index
- **Objects** เก็บ key-value pairs เข้าถึงด้วย property name
- **Array Methods** มี map, filter, reduce, forEach ฯลฯ
- **Object Methods** มี keys(), values(), entries() ฯลฯ
- **Array of Objects** ใช้สำหรับข้อมูลที่ซับซ้อน
- ใช้ immutable methods เมื่อเป็นไปได้
- ระวัง reference type behavior ของ arrays และ objects

---

## แหล่งอ้างอิง

- [MDN - JavaScript Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
- [MDN - JavaScript Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
- [JavaScript.info - Arrays](https://javascript.info/array)
- [JavaScript.info - Objects](https://javascript.info/object)
