🏠 Home / Hub

🟨 JS Lesson 11 — Prototype Chain

← Back to JS Menu  |  🏠 Hub

1. Prototype ဆိုတာ ဘာလဲ?

JavaScript မှာ object တိုင်းမှာ hidden [[Prototype]] link ရှိတယ်
Property ကိုရှာတဲ့အခါ — own object မှာ မတွေ့ → prototype ဆင်းရှာ → prototype ရဲ့ prototype → null ထိ
ဒါကို Prototype Chain လို့ခေါ်တယ်
// class ရေးလိုက်တဲ့အခါ actually prototype သုံးနေတာ
class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} speaks`; }
}

const dog = new Animal("Rex");

// Prototype chain visualization:
// dog → Animal.prototype → Object.prototype → null

// Check prototype
Object.getPrototypeOf(dog) === Animal.prototype;  // true
Animal.prototype.constructor === Animal;           // true

// dog ရဲ့ own properties
Object.keys(dog);             // ["name"]
"speak" in dog;               // true (chain ထဲမှာ ရှိလို့)
dog.hasOwnProperty("name");   // true
dog.hasOwnProperty("speak");  // false (prototype ထဲမှာ)

2. Prototype ကို တိုက်ရိုက် ထည့်ခြင်း (Old-style OOP)

// ES5 style — class မတိုင်ခင် ဒီလို ရေးခဲ့ကြတယ်
function Person(name, age) {
  this.name = name;   // instance property
  this.age  = age;
}

// Prototype ထဲ method ထည့်ခြင်း
Person.prototype.greet = function() {
  return `Hi, I'm ${this.name}`;
};

Person.prototype.birthday = function() {
  this.age++;
  return `Happy birthday ${this.name}! Now ${this.age}`;
};

const p1 = new Person("Ko Ko", 25);
const p2 = new Person("Ma Ma", 22);

p1.greet();    // "Hi, I'm Ko Ko"
p2.greet();    // "Hi, I'm Ma Ma"

// Both share the SAME greet function (memory efficient!)
p1.greet === p2.greet;  // true

// ES6 class ကို prefer ပါ — prototype ကို abstraction လုပ်ပေးထားတာ
💡 class methods are stored on prototype automatically — memory efficient (not copied per instance)

3. Object.create() — Prototype-based Inheritance

// Object.create(proto) = proto ကို prototype အဖြစ်သတ်မှတ်ပြီး object ဆောက်

const animalProto = {
  speak() { return `${this.name} says ${this.sound}`; },
  eat(food) { return `${this.name} eats ${food}`; }
};

// dog → animalProto (as prototype)
const dog = Object.create(animalProto);
dog.name  = "Rex";
dog.sound = "Woof";

dog.speak();  // "Rex says Woof"
dog.eat("bone");  // "Rex eats bone"

// Check prototype chain
Object.getPrototypeOf(dog) === animalProto;  // true

// Factory function pattern with Object.create
function createDog(name, breed) {
  const dog = Object.create(animalProto);
  dog.name  = name;
  dog.sound = "Woof";
  dog.breed = breed;
  dog.bark  = function() { return `${this.name}: WOOF!`; };
  return dog;
}

const rex = createDog("Rex", "Husky");
rex.speak();  // from animalProto
rex.bark();   // own method

4. Built-in Prototype — Array, String, Object

// Built-in types မှာ prototype methods တွေ ရှိပြီးသား
const arr = [1, 2, 3];
// arr → Array.prototype → Object.prototype → null

// Array.prototype methods
arr.map(x => x * 2);     // from Array.prototype
arr.filter(x => x > 1);  // from Array.prototype
arr.toString();           // from Object.prototype

// String.prototype
"hello".toUpperCase();    // from String.prototype
"world".includes("orl"); // from String.prototype

// Custom method ထည့်ခြင်း (prototype extension) — production မှာ မကောင်း
Array.prototype.sum = function() {
  return this.reduce((acc, n) => acc + n, 0);
};
[1, 2, 3, 4].sum();  // 10

// ⚠️ Built-in prototypes မပြင်ပါနဲ့ (polyfills မှ အပ)
// naming conflicts နဲ့ unexpected behaviors ဖြစ်နိုင်
⚠️ Never modify built-in prototypes (Array.prototype, Object.prototype) in production code!

5. Mixin — Multiple "Inheritance" Pattern

// JavaScript မှာ single inheritance ပဲ ရတယ်
// Mixin = behavior တွေကို copy လုပ်ပြီး object ထဲ ထည့်ခြင်း

const Serializable = {
  serialize() {
    return JSON.stringify(this);
  },
  static deserialize(json) {
    return JSON.parse(json);
  }
};

const Validatable = {
  validate() {
    return Object.entries(this).every(([k, v]) => v !== null && v !== undefined);
  }
};

const Timestampable = {
  setCreatedAt() {
    this.createdAt = new Date().toISOString();
  }
};

class User {
  constructor(name, email) {
    this.name  = name;
    this.email = email;
  }
}

// Mix in behaviors with Object.assign
Object.assign(User.prototype, Serializable, Validatable, Timestampable);

const user = new User("Ko Ko", "ko@example.com");
user.setCreatedAt();
user.validate();    // true
user.serialize();   // '{"name":"Ko Ko","email":"ko@example.com",...}'

// Class မixin syntax (cleaner)
const withLogging = (Base) => class extends Base {
  log(msg) { console.log(`[${this.constructor.name}] ${msg}`); }
};

class Service extends withLogging(class {}) {
  doWork() { this.log("Working..."); }
}

📌 Prototype Key Points

ConceptDescriptionHow to Use
Prototype chainProperty lookup chain to nullAutomatic — how inheritance works
Object.getPrototypeOf(x)Get x's prototypeDebugging, checking chain
hasOwnProperty(k)Own vs inheritedx.hasOwnProperty("name")
instanceofCheck prototype chainx instanceof ClassName
Object.create(proto)Set prototype manuallyPrototype-based patterns
MixinCopy methods from objectsObject.assign(Class.prototype, mixin)

← JS 10  |  Next: JS 12 → Closures & Scope →

📌 Study Checklist