JavaScript อนุญาตให้แก้ไข Prototype ของ Constructor Function ได้ตลอดเวลา (Runtime) การเปลี่ยนแปลงจะส่งผลต่อ Instance ทั้งหมดที่สร้างจาก Constructor นั้น รวมถึง Instance ที่สร้างก่อนการแก้ไข
ตัวอย่างโค้ด
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Modify Prototype</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
.result { font-size: 20px; font-weight: 500; color: blueviolet; }
</style>
</head>
<body>
<h1>Modifying Prototypes ใน JavaScript</h1>
<div class="result"></div>
<button class="Btn">คลิกที่นี่</button>
<h3>คลิกปุ่มด้านบนเพื่อดู Prototype Function ก่อนและหลังแก้ไข</h3>
<script>
const resEle = document.querySelector(".result");
const BtnEle = document.querySelector(".Btn");
function Person(name, age, occupation) {
this.name = name;
this.age = age;
this.occupation = occupation;
}
Person.prototype.displayInfo = function() {
return `Name: ${this.name} Age: ${this.age} Occupation: ${this.occupation}<br>`;
};
const person1 = new Person("Shawn", 20, "student");
const person2 = new Person("Rohan", 25, "Manager");
BtnEle.addEventListener("click", () => {
// ก่อนแก้ไข
resEle.innerHTML = "Before Modifying Prototype<br>" +
person1.displayInfo() + person2.displayInfo();
// แก้ไข Prototype Method (Runtime)
Person.prototype.displayInfo = function() {
return `Occupation: ${this.occupation} Age: ${this.age} Name: ${this.name} <br>`;
};
// หลังแก้ไข - Instance เดิมก็ได้ Method ใหม่!
resEle.innerHTML += "<br>After Modifying Prototype<br>" +
person1.displayInfo() + person2.displayInfo();
});
</script>
</body>
</html>
Prototype Modification Behavior
function Person(name) { this.name = name; }
Person.prototype.greet = () => `Hi ${this.name}`;
const p1 = new Person("A");
console.log(p1.greet()); // "Hi A"
// Modify Prototype
Person.prototype.greet = () => `Hello ${this.name}`;
console.log(p1.greet()); // "Hello A" - Instance เดิมได้ Method ใหม่!
// Add New Method
Person.prototype.sayBye = () => `Bye ${this.name}`;
console.log(p1.sayBye()); // "Bye A" - Instance เก่ามี Method ใหม่!
⚠️ ข้อควรระวังและ Best Practices
- ไม่ควรแก้ไข Built-in Prototypes (Array.prototype, Object.prototype, String.prototype) - ก่อให้เกิด Conflict
- Debugging ยาก: Method Source ไม่ชัดเจน มาจาก Prototype หรือ Instance
- Performance: Prototype Lookup ช้ากว่า Own Property เล็กน้อย
- การ Override: Instance สร้าง Own Property ชื่อเดียวกันได้ (Shadowing)
ES6 Class - Static Methods ไม่ได้อยู่ที่ Prototype
class Person {
static species = "Human"; // Static - ไม่ได้ที่ Prototype
constructor(name) { this.name = name; }
greet() { return `Hi ${this.name}`; } // Prototype Method
}
Person.species; // "Human"
Person.prototype.species; // undefined
ผลลัพธ์
ก่อนแก้ไข: Name: Shawn Age: 20 Occupation: student, Name: Rohan Age: 25 Occupation: Manager
หลังแก้ไข: Occupation: student Age: 20 Name: Shawn, Occupation: Manager Age: 25 Name: Rohan