كل كائن JavaScript له رابط مخفي إلى كائن آخر يُسمى prototype. عند الوصول إلى خاصية، يبحث JS عن الخاصية في الكائن نفسه أولاً، ثم يسير في prototype chain حتى يجد الخاصية أو يصل إلى null. هذا هو التفويض، وليس النسخ.
js
const animal = {
speak() { return `${this.name} makes a sound`; },
};
const dog = Object.create(animal); // dog's prototype IS animal
dog.name = "Rex";
dog.speak(); // "Rex makes a sound" — found on the prototype
Object.getPrototypeOf(dog) === animal; // true
dog.hasOwnProperty("speak"); // false — it's inherited, not own
dog.hasOwnProperty("name"); // true
كيف تستخدم الأصناف (Classes) هذا
class هي سكر نحوي فوق الأنماط الأساسية. الدوال تعيش مرة واحدة على prototype، مشتركة بين جميع الحالات (لا يتم نسخها لكل كائن):
js
class Dog {
constructor(name) { this.name = name; }
speak() { return `${this.name} barks`; } // on Dog.prototype
}
const d = new Dog("Rex");
Object.getPrototypeOf(d) === Dog.prototype; // true
إذاً d.speak لا يتم تخزينها على d — يتم العثور عليها بالمسير لأعلى إلى Dog.prototype. ولهذا السبب جميع الكلاب تشترك في دالة speak واحدة (فعال من حيث الذاكرة).
لماذا يهم
فهم السلسلة يشرح: لماذا الحالات تشترك في الدوال، لماذا تغيير prototype يؤثر على جميع الكائنات المرتبطة، كيف يعمل instanceof (يتحقق من السلسلة)، وتكلفة سلاسل البحث الطويلة.
هو الأساس تحت class، والعمليات المدمجة (Array.prototype.map)، والوراثة.
