Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

การแก้ไข Prototypes ใน JavaScript (Prototype Modification)

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