Skip to content
Prev Previous commit
Next Next commit
Translate the "Objects: the basics" section to Thai
  • Loading branch information
EpicHigh committed Apr 15, 2024
commit b7361dd04d3c7a75849485171ef91a4516615c85
80 changes: 80 additions & 0 deletions 1-js/04-object-basics/06-constructor-new/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,83 @@
การใช้ `{...}` ช่วยให้เราสร้างออบเจ็กต์ได้ แต่ในกรณีที่ต้องการสร้างออบเจ็กต์หลายๆ ตัวที่มีลักษณะคล้ายกัน เช่น ผู้ใช้หลายคน, เมนูหลายรายการ ฯลฯ การใช้ `{...}` ซ้ำๆ อาจไม่ใช่วิธีที่ดี

ในกรณีนี้เราสามารถใช้ฟังก์ชัน constructor ร่วมกับตัวดำเนินการ `"new"` ได้

## ฟังก์ชัน Constructor

โดยปกติแล้ว ฟังก์ชัน constructor เป็นฟังก์ชันธรรมดา แต่มีข้อตกลงสองประการ:

1. ชื่อฟังก์ชันจะขึ้นต้นด้วยตัวพิมพ์ใหญ่เสมอ
2. ควรเรียกใช้งานผ่านตัวดำเนินการ `"new"` เท่านั้น

ตัวอย่างเช่น:

```js run
function User(name) {
this.name = name;
this.isAdmin = false;
}

*!*
let user = new User("Jack");
*/!*

alert(user.name); // Jack
alert(user.isAdmin); // false
```

เมื่อฟังก์ชันถูกเรียกผ่าน `new` จะเกิดขั้นตอนดังนี้:

1. มีการสร้างออบเจ็กต์ใหม่ขึ้นมาเปล่าๆ และกำหนดให้เป็น `this`
2. ทำงานในส่วนบอดี้ของฟังก์ชัน ซึ่งมักจะมีการปรับแต่ง `this` และเพิ่มคุณสมบัติใหม่ๆ เข้าไป
3. คืนค่า `this`

กล่าวอีกนัยหนึ่ง `new User(...)` สามารถเทียบได้กับ:

```js
function User(name) {
*!*
// this = {}; (โดยนัยยะ)
*/!*

// เพิ่มคุณสมบัติลงใน this
this.name = name;
this.isAdmin = false;

*!*
// return this; (โดยนัยยะ)
*/!*
}
```

ดังนั้น `let user = new User("Jack")` จะให้ผลลัพธ์เหมือนกับ:

```js
let user = {
name: "Jack",
isAdmin: false
};
```

ซึ่งหากเราต้องการสร้าง user อื่นๆ เพิ่มเติม ก็เรียกใช้ `new User("Ann")`, `new User("Alice")` เป็นต้น โดยจะสั้นกว่าและอ่านง่ายกว่าการใช้ออบเจ็กต์ลิเทอรัลซ้ำๆ มากๆ

จึงสรุปได้ว่า จุดประสงค์หลักของ constructor คือ การนำโค้ดที่ใช้ในการสร้างออบเจ็กต์มาใช้ซ้ำได้ง่ายขึ้น

กลับมาเน้นย้ำอีกครั้ง -- ในแง่หลักการแล้ว ฟังก์ชันอะไรก็ตาม (ยกเว้น arrow function ที่ไม่มี `this`) สามารถนำมาเป็น constructor ได้ สามารถเรียกใช้งานผ่าน `new` และจะดำเนินการตามขั้นตอนข้างต้น การตั้งชื่อให้ขึ้นต้นด้วยตัวอักษรพิมพ์ใหญ่เป็นแค่ข้อตกลงร่วมกัน เพื่อให้ชัดเจนว่าฟังก์ชันนี้ควรเรียกใช้ผ่าน `new` เท่านั้น

````smart header="new function() { ... }"
กรณีที่การสร้างออบเจ็กต์ที่ซับซ้อนมีโค้ดหลายบรรทัด เราสามารถครอบมันด้วย constructor function และเรียกใช้ทันทีได้ ดังนี้:

```js
// สร้างฟังก์ชันและทันทีเรียกใช้ผ่าน new
let user = new function() {
this.name = "John";
this.isAdmin = false;

// ...โค้ดอื่นๆ ในการสร้าง user
// อาจมีตรรกะและคำสั่งที่ซับซ้อน
// มีตัวแปรภายใน ฯลฯ
};
```

Constructor ดังกล่าวไม่สามารถเรียกใช้ซ้ำได้อีก เนื่องจากไม่ได้ถูกเก็บไว้ที่ใดเลย ถูกสร้างและเรียกใช้ในทันที เทคนิคนี้ใช้เพื่อห่อหุ้มกระบวนการสร้างออบเจ็กต์ที่ซับซ้อนไว้ด้วยกัน และไม่มีแผนจะนำมาใช้ซ้ำอีกในอนาคต
````