Jokaisella JavaScript-objektilla on piilotettu linkki toiseen objektiin, jota kutsutaan sen prototyyppiksi. Kun käytät ominaisuutta, JS etsii sitä ensin objektista itsestään, sitten kulkee prototype chain -ketjua ylöspäin, kunnes se löytää ominaisuuden tai saavuttaa null. Tämä on delegointi, ei kopiointi.
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
Miten luokat käyttävät sitä
class on syntaktinen sokeri prototyyppien yli. Metodit elävät kerran prototyypissä, jaettuna kaikilla ilmentymillä (ei kopioida objektia kohden):
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
Joten d.speak ei ole tallennettu d:hen — se löydetään kulkemalla ylöspäin Dog.prototypeiin. Siksi kaikki koirat jakavat yhden speak-funktion (muistin kannalta tehokas).
Miksi sillä on merkitystä
Ketjun ymmärtäminen selittää: miksi ilmentymät jakavat metodeja, miksi prototyypin muuttaminen vaikuttaa kaikkiin linkitettyihin objekteihin, miten instanceof toimii (se tarkistaa ketjun), ja pitkien hakuketjujen kustannukset.
Se on perusta class-määreelle, sisäänrakennetuille (Array.prototype.map) ja perintöille.
